jamiebuilds / ghost-lang

:ghost: A friendly little language for you and me.
302 stars 10 forks source link

Default arguments #19

Open aleclarson opened 5 years ago

aleclarson commented 5 years ago

I assume it's just (a = 1, b = 2) and works like TypeScript.

jamiebuilds commented 5 years ago

I've thought about not including default arguments and just encouraging:

There's a couple different properties I don't like about this syntax:

let fn = fn (a: String = "default", b: String = "default") {
  # ...
}
  1. Function reads like (a: String, b: String) but it's actually (a: String?, b: String?)
  2. With more complex parameter lists you end up with very long lines that you then need to split like this:
let fn = fn (
  a: String = "default",
  b: String = "default",
  c: String = "default",
  d: String = "default",
) {
  # ...
}

(which should be valid syntax to split on multiple lines, but sucks to have to do frequently)

Instead I think I'd prefer something in the realm of:

let fn = fn (a: String?, b: String?) {
  a ?= "default"
  b ?= "default"
  # ...
}
aleclarson commented 5 years ago

Is ?= official syntax?

I prefer not repeating the variable names if I can get away with it. The first example is readable to me. :)

jamiebuilds commented 5 years ago

lol, the language is like 10% designed, nothing is implemented, there's no real "official" anything yet :P

Yes, it's perfectly readable, but it's also a very very simple function signature, when you start having function arguments with defaults and more complex types, the signature starts turning into a nightmare.

let createMerger = fn <Value: Number | String> (value: Value, merge: fn (other: Value): Value = fn (other: Value): Value { value + other }) {
  # ...
}

I think it's better to encourage people to write things more like this:

type Mergable = Number | String
type Merge<Value> = fn (other: Value): Value

let createMerger = fn <Value: Mergable> (value: Value, merge: Merge<Value>?) {
  merge ?= fn (other) { value + other }
  # ...
}
aleclarson commented 5 years ago

Thank you for killing extends in generic clauses. That will be the first "official" thing in Ghost. :P

Yes, it's perfectly readable, but it's also a very very simple function signature, when you start having function arguments with defaults and more complex types, the signature starts turning into a nightmare.

I thought we wanted to encourage vertical flow?

let createMerger = fn <Value: Number | String> (
  value: Value, 
  merge: fn (other: Value): Value = fn (other: Value): Value { value + other }
) {
  # [insert useful shit]
}

But I agree that function literals should not be allowed as default arguments. Those can go in the function body where they belong.