Hacker News new | ask | show | jobs
by tom_mellior 2082 days ago
I wonder what "loose syntax" is supposed to mean here. No semicolons at the ends of lines? OK. Optional commas between function arguments? Hum. But at the same time this seems to require colons after... what exactly? Variable read accesses in argument lists? Unintuitive and not exactly "loose".
3 comments

> But at the same time this seems to require colons after... what exactly?

not 100% sure but it kind of looks like copper's Whole Dealâ„¢ are "object-functions" (closures?) and you use colons to get an object function's return value. something like this

  adder = [a b]{ ret(this.a + this.b) }
  x = adder(3 5)
  print(x.a x.b x:) # 3 5 8
(i looked at the docs for like 10 minutes, could be wrong)
You are correct. "object-function" is basically like in Javascript: It's an object (having members) and an executable body. The colons are a shorthand for function call. ie myfunc()

In Copper, variables only store functions. This separates routine from data so you never end up with null pointer errors like in languages that have Any Types or pointers. Functions can return data, so you end up having function calls everywhere. a=5 is basically a={ret(5)}

In your above example the correct first line would be: adder = [a b] { ret(+(a: b:)) }

Parameters to a function are those that are not assigned data, whereas members are: add = [Param, Member=10) { ret(+(Param: this.Member:)) }

Now you can probably see what's wrong with your third line.

yeah, i think i get it now. but if variables can only store functions, how would you write something like this in Copper?

  x = foo()
  bar(x.a, x.b)
x = foo()

bar(x.a: x.b:)

Functions can return data. So say, a=5, then to get the value of 5 out, all you have to do is call the function a.

Edit: I'm assuming foo() here returns an object with members "a" and "b". An example of such a function-object would be:

foo = [] { ret( [a=5, b=10] ) }

right, but doesn't that contradict this:

> "in Copper, variables only store functions"

because here, `x` clearly stores an object... is this about the whole "object-function" thing where Copper doesn't really distinguish the two?

(btw i'm sure this is explained in the docs... but maybe this'll help folks like me who often just read the comments)

Copper does not distinguish between function and object. An object-function has two parts: the member part and the executable body. In C++, it's analogous to:

class FunctionObject {

FunctionObject* members[];

void* operator() { /* executable body */ }

};

Isn't the trailing colon thing also in Ruby? I thought I remembered seeing something like this elsewhere where it also did not make much sense
The colon is a shorthand for (). Incidentally, it also makes for lots of little smiley faces everywhere.
No semicolons are ever required. It is loose syntax in that most anything, including this paragraph, is valid and readable code
That's still not very helpful to me. You might want to explain it a bit more in the README.

For example, taking this line from the first example:

    this.peek = +(this.a: this.b:)
If I replace this by:

    this.peek = +(this.a: this.b:
(note the dropped closing parenthesis) and leave everything else as is, that will not be a syntax error?

I know that Forth is "loose syntax" in that Forth code is just a sequence of white-space separated words, so your comment and mine are both syntactically valid Forth, but without meaningful semantics. But Forth does not use parenthesized function calls the way Copper does.

I see what you're getting at. Yes, a ) is needed... eventually. I think the key with "loose" is that it's forgiving. You won't encounter many syntax errors in average programming because the syntax has few rules. In that case, "very simple" would be better said than "loose".