Skip to content

Instantly share code, notes, and snippets.

@chenglou
Last active September 7, 2017 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chenglou/a8078054d3e22524b30ff9e7a58a230f to your computer and use it in GitHub Desktop.
Save chenglou/a8078054d3e22524b30ff9e7a58a230f to your computer and use it in GitHub Desktop.
Revised syntax labelled function argument. **The only difference is between ~ and :**
/* == definition == */
/* two labelled arguments, one unlabelled */
let display = (~message, ~person, time) => 1;
/* with default value */
let display = (~message="hello", ~person="Reason", time) => 1;
/* with type annotation */
let display = (~message: string, ~person: string, time: float) => 1;
/* type annoation and with default */
let display = (~message: string="hello", ~person: string="Reason", time: float) => 1;
/* == call == */
/* normal */
display(~message="hey", ~person="Reason", 2.0);
/* call with punning, aka ~message=message */
display(~message, ~person, 2.0);
/* == type definition == */
/* normal */
type d = (~message: string, ~person: string, float) => int;
/* with default */
type d = (~message: string=?, ~person: string=?, float) => int;
/* == definition == */
/* two labelled arguments, one unlabelled */
let display = (:message, :person, time) => 1;
/* with default value */
let display = (:message="hello", :person="Reason", time) => 1;
/* with type annotation */
let display = (:message: string, :person: string, time: float) => 1;
/* type annoation and with default */
let display = (:message: string="hello", :person: string="Reason", time: float) => 1;
/* == call == */
/* normal */
display(:message="hey", :person="Reason", 2.0);
/* call with punning, aka :message=message */
display(:message, :person, 2.0);
/* == type definition == */
/* normal */
type d = (:message: string, :person: string, float) => int;
/* with default */
type d = (:message: string=?, :person: string=?, float) => int;
@cullophid
Copy link

Both make the functions difficult to read:(
Would it not be preferable to separate the type signature from the definition? Like in elm/haskell?
I know this isn't the topic here, but I think that's why this is so complicated

@cullophid
Copy link

Adding types to a function often makes the code much simpler to understand, so we should make it as simple as possible to write type signatures

@pugnascotia
Copy link

Prefer #2 partly because it reminds me of Smalltalk

@mattapperson
Copy link

#1 for sure, number 2 feels confusing to have the preceding : then also using it to separate from the type.
That said... I agree with @cullophid

@mjmahone
Copy link

: usually has real semantic meaning, that other characters wouldn't have: in English, it's often used to separate a "key" clause (short, tl;dr) from a "descriptive" clause. In Objective-c it's functionVariableName: functionVariableArgument. In Javascript it's key: value inside of objects. Putting it in the front results in :key=value which reverses the typical meaning. ~'s only semantic meaning, that I think is commonly used, is "approximately" in math. As such, it's probably a better character to overload with meaning, especially as it seems (to me) to have fewer major-language (JS especially) meaning clashes.

@ShalokShalom
Copy link

ShalokShalom commented Sep 1, 2017

Maybe consider the possibility to use one of the both for an other sugar, this might make the decision for this one easier.

@fstiffo
Copy link

fstiffo commented Sep 2, 2017

Calling a function using parenthesis destroys the beauty of currying syntax

@oteku
Copy link

oteku commented Sep 4, 2017

Agree with @fstiffo : Why create more verbose syntax ?

About the initial question I prefer the first one (~) like in OCaml
The second (:) may be confusing about the meaning of ':' symbol in ReasonML

@ckknight
Copy link

ckknight commented Sep 6, 2017

I prefer ~ over : only because : is already meaningful for types - wouldn't want to overload that meaning.

@bluddy
Copy link

bluddy commented Sep 6, 2017

I vote for

/* two labelled arguments, one unlabelled */
let display = (@message, @person, time) => 1;
/* with default value */
let display = (@message="hello", @person="Reason", time) => 1;
/* with type annotation */
let display = (@message: string, @person: string, time: float) => 1;
/* type annoation and with default */
let display = (@message: string="hello", @person: string="Reason", time: float) => 1;

/* == call == */

/* normal */
display(@message="hey", @person="Reason", 2.0);
/* call with punning, aka @message=message */
display(@message, @person, 2.0);

/* == type definition == */

/* normal */
type d = (@message: string, @person: string, float) => int;
/* with default */
type d = (@message: string=?, @person: string=?, float) => int;

@kliron
Copy link

kliron commented Sep 7, 2017

Tilde please. Like others have said, I think overloading the meaning of symbols is not a wise thing to do. The tilde is unique and while it might seem weird the first 5 times a newcomer looks at it, it is easy to digest. Thowing : everywhere is awfully confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment