-
Notifications
You must be signed in to change notification settings - Fork 15
7ML7W Factor Day 1 Stack On Stack Off
Present: a bunch of people, plus one gale howling at the rafters.
Leo: We're perfectly safe.
All: [are unreassured]
A rubric is ably rubred by Adam, and we're off.
What do we want to concentrate on? The main problem we had was installing it.
[installation chat censored]
Some chat about stack-based languages ensues, and a talk about Joy (another such language) is referred to. A link might even follow after the meeting!
Elena: Do we know why it's called Factor?
It appears that we don't, nor why its logo is a dinosaur and a pyramid.
We've got a Listener, not a terminal REPL. You can save an image of a running program? Nobody tried that though it seems.
Mudge: Found it a bit weird being gui-bound, like we don't even get to FILES until day 2.
Murray: There is a terminal version, it's just really hard to find.
Adam: there's really cool documentation built into the listener, like tutorials and wotnot.
Murray: and, like, space invaders
All: whaaaaaaat
Okay, so it's backwards, what's good about that?
Murray: I assume the parser for this is like, really simple. Whitespace means tokens, end of.
What about quoting with [ ... ]
though? Are those functions?
Murray: So I thought ]
might be a function, based on some poking I
did into the documentation syntax, which is a completely separate thing,
and had some special call(
function. That's as far as I got
though.
TODO: investigate this, computation club!
James C: can you just push a [
onto the stack and not close it?
Turns out you can't, so a quote push is an atomic thing.
Adam: You're putting a lot of load on the developer having to model this stack in their head - why is this good?
Mark: I think of these types of language as really low-level - there's simplicity of implementation and computational model.
James C: this is the underlying model for lots of stuff - Ruby code gets compiled down to something that gets run on a stack machine
[we take a look at the math operators]
Adam: there's no precedence or parentheses - the parse tree is defined by the arity and the order you add the functions^H^H^H^H^H^H^H words.
Some discussion of print
vs .
ensues. .
They both pop something
off the stack and print it - .
handles non-string values.
Murray: It's weird that you get special syntax for lists but not maps. Like, aren't maps as important?
James C: Are they actually maps or just arrays?
Adam: It's like the opposite of lua, where arrays were special cases of maps, vs. here where a map is just an array where all its members are pairs.
Mudge: What if you define a key twice in a map?
[James A demonstrates no error is raised, and of
returns the first
declared value]
James C: Okay so they're pretend maps.
Why do you need both at
and of
? The only difference is argument
order.
Murray: Are we just going to end up with a grab-bag of these functions where the only difference is which way around you pass the args?
James C: I guess you could justify it by saying "key of hash" and "hash at key", that sort of makes sense.
Some discussion of whether these are akin to lambdas. Mark points out that they don't close over any context, because there isn't a context to close over.
You can't push any old nonsense, it needs to parse, but it won't evaluate until you call it.
James C: it's like putting a list on the stack, only the list can be executed. When you start processing that quotation, the first thing starts working on the stack, then the next thing and so on. Another way they're not like lambdas - they don't take arguments, they operate on the same stack.
[some macro chat that goes over my head]
Leo: people keep saying "macros" and I don't understand the term (ed: :fistbump:)
Tuzz: it's a bit like a recording of actions, kinda like a vim macro? [that's a joke but gains assent]
Murray: they are exactly like functions in factor, in that they're a word that takes some amount of stuff off the stack, and puts back another amount.
Adam: if you refer to functions/words in a macro, is there some level of compilation that needs to know they exist before you can put them on the stack in quotes?
Apparently so (if the Listener is to be believed):
Some variable chat - we haven't met them. Do they exist? Maybe they don't! You just have the stack.
Okay, so everything but f
is truthy. Good. Wow, though, conditionals
seem hard to visually scan.
Tuzz: Maybe just ignore that the if
comes at the end, you've still
got condition / consequent / alternative.
Mudge: Okay, so the quotes handle short-cut evaluation for you, so you can just bin expensive computations for the branch not taken.
Mudge: Immediately I'm annoyed by nip
.
[interlude on PHP naming history conveniently censored by the gale]
Okay so you can manipulate the stack, but really we'll use...
Okay, we look at bi
which applies sequential quotes to a single value
and pushes both onto the stack.
IN: scratchpad 1 [ 2 + ] [ 4 * ] bi
--- Data stack:
3
4
Then tri
does the same for three.
Leo: How is this useful? Specifically how is exactly two useful?
Mudge: Can you even have a variadic function in Factor, though? You need to know how much of the stack a word is going to take.
Murray: Maybe there is a solution to the variadic thing, but most of the time you're using two or three things?
Murray: how the hell do you remember what these things mean? bi*
for example, wat?
IN: scratchpad 1 2 [ 4 * ] [ 6 - ] bi*
--- Data stack:
4
-4
We conclude that the names are bad.
[some parser combinator chat goes over my head]
- How do you do 3^2 + 4^2?
3 3 * 4 4 * +
OR
3 4 [ dup * ] bi@ + .
- with
USE: math.functions
, do sqrt(3^2 + 4^2)
3 sq 4 sq + sqrt
OR
3 4 [ sq ] bi@ sqrt
It's good that the combinator version is longer. A language that discourages golfing!
- with
1 2
on the stack, how do you get to1 1 2
1 2 over swap
So over swap
is an idiom for "duplicate the second item on the stack"?
- with
USE: ascii
put your name on the stack and hello yourself IN CAPS
"james" "hello, " append >upper .
-
reduce
takes a sequence, initial value, and a quotation, and applies the quotation to the sequence starting from the initial. Do a thing (I missed)
IN: scratchpad { 1 4 17 9 11 } 0 [ + ] reduce .
42
- Now calculate the sum of numbers 1-100 without manually writing the
sequence. Use
math.ranges
IN: scratchpad USE: math.ranges
IN: scratchpad USE 100 [1,b]
--- Data stack:
T{ range f 1 100 1 }
IN: scratchpad 0 [ + ] reduce .
5050
Joel: Can you type in that pretty-printed range syntax, i.e. is [1,b]
just a convenience?
YOU TOTALLY CAN
Chris Z: (via slack) Here is the docs for
‘literals’
which includes the array and quotation syntax. T{ }
is for tuples.
-
map
takes a sequence and a quotation and does what you'd expect. Print the squares from 1 to 10.
IN: scratchpad 10 [1,b] [ sq ] map .
{ 1 4 9 ... }
- Write a line of code that, given a number 1-99, returns the two digits as a sequence
IN: scratchpad 42 dup 10 /i swap 10 mod
--- Data stack:
4
2
- Do the same thing for any number of digits. :'(
IN: scratchpad 12345 number>string [ 1string string>number ] each
[I'm not sure where number>string
comes from here, it errors on my
Listener.]
At this point we start emoji-ing using byte conversions.
[some really deep unicode plane chat censored because c'mon]
Leo: That's the most fun I've had all meeting.
[I probably shouldn't have censored it eh.]
Are people using this for production apps? Does anyone care? Is concatenative programming a deep subculture that will rise up to overwhelm us all?
We don't really know.
Dmitry: I think it might be easier to prove properties of programs written in this?
We look at some terrifying factor code:
call( x -- y )
Is this variadic support? Does x
define how many values it pops off
the stack? Maybe?
[ALL HIGH-MINDED CHAT STOPS AS JAMES A GETS TETRIS RUNNING]
[IT GETS HIGH-MINDED AGAIN AS WE TRY TO RUN ARBITRARILY-MANY TETRISES USING MAP]
[WINDOWS FLY EVERYWHERE, FACTOR CRASHES]
Eventually we settle on 20 as a reasonable number of tetrises to run concurrently.
Have we settled on Tuesdays for this language, then? YES.
Volunteers for next meeting: ABEER! YES!
Seemed decent for an introductory chapter. Interesting, we've clearly not seen everything yet. What's it for, though? Do we know yet? I guess not, but it's just weird enough that doing normal things is interesting.
Tuzz: Are there safety features? You can pop anything off the stack, can you be sure you're only popping the right things off?
Mudge: I just quite like paradigms.
Mark: There's definitely a pragmatic use for languages in this family, but maybe this is just one created for fun - there's working versions of Forth out there in the world, and, y'know, spaceships.
Spaceships!
So say we all.
We really liked the side-by-side code'n'book (thanks James A for driving!). Let's make sure to do that in future.
- Home
- Documentation
- Choosing a Topic
- Shows & Tells
- Miscellaneous
- Opt Art
- Reinforcement Learning: An Introduction
- 10 Technical Papers Every Programmer Should Read (At Least Twice)
- 7 More Languages in 7 Weeks
- Lua, Day 1: The Call to Adventure
- Lua, Day 2: Tables All the Way Down
- Lua, Day 3
- Factor, Day 1: Stack On, Stack Off
- Factor, Day 2: Painting the Fence
- Factor, Day 3: Balancing on a Boat
- Elm, Day 1: Handling the Basics
- Elm, Day 2: The Elm Architecture
- Elm, Day 3: The Elm Architecture
- Elixir, Day 1: Laying a Great Foundation
- Elixir, Day 2: Controlling Mutations
- Elixir, Day 3: Spawning and Respawning
- Julia, Day 1: Resistance Is Futile
- Julia, Day 2: Getting Assimilated
- Julia, Day 3: Become One With Julia
- Minikanren, Days 1-3
- Minikanren, Einstein's Puzzle
- Idris Days 1-2
- Types and Programming Languages
- Chapter 1: Introduction
- Chapter 2: Mathematical Preliminaries
- Chapter 3: Untyped Arithmetic Expressions
- Chapter 4: An ML Implementation of Arithmetic Expressions
- Chapter 5: The Untyped Lambda-Calculus
- Chapters 6 & 7: De Bruijn Indices and an ML Implementation of the Lambda-Calculus
- Chapter 8: Typed Arithmetic Expressions
- Chapter 9: The Simply-Typed Lambda Calculus
- Chapter 10: An ML Implementation of Simple Types
- Chapter 11: Simple Extensions
- Chapter 11 Redux: Simple Extensions
- Chapter 13: References
- Chapter 14: Exceptions
- Chapter 15: Subtyping – Part 1
- Chapter 15: Subtyping – Part 2
- Chapter 16: The Metatheory of Subtyping
- Chapter 16: Implementation
- Chapter 18: Case Study: Imperative Objects
- Chapter 19: Case Study: Featherweight Java
- The New Turing Omnibus
- Errata
- Chapter 11: Search Trees
- Chapter 8: Random Numbers
- Chapter 35: Sequential Sorting
- Chapter 58: Predicate Calculus
- Chapter 27: Perceptrons
- Chapter 9: Mathematical Research
- Chapter 16: Genetic Algorithms
- Chapter 37: Public Key Cryptography
- Chapter 6: Game Trees
- Chapter 5: Gödel's Theorem
- Chapter 34: Satisfiability (also featuring: Sentient)
- Chapter 44: Cellular Automata
- Chapter 47: Storing Images
- Chapter 12: Error-Correcting Codes
- Chapter 32: The Fast Fourier Transform
- Chapter 36: Neural Networks That Learn
- Chapter 41: NP-Completeness
- Chapter 55: Iteration and Recursion
- Chapter 19: Computer Vision
- Chapter 61: Searching Strings
- Chapter 66: Church's Thesis
- Chapter 52: Text Compression
- Chapter 22: Minimum spanning tree
- Chapter 64: Logic Programming
- Chapter 60: Computer Viruses
- Show & Tell
- Elements of Computing Systems
- Archived pages