Closed IwanKaramazow closed 1 year ago
Could you explain? I think that I will be able to write own operator -- :+:
for example.
And use
let sum = (a, b) => a :+: b
We need this. It's essential for a language to be used as DSL. That's one of the major reasons.
Use cases like >=> can be replaced with function calls to flatMap or bind, but I can't find a good looking workaround for doing stuff like...
Where <$> is a Option.map function and <*> is Option.apply. A function someFunc
which takes pure int inputs can be converted to take monad types like option(int)
.
someFunc: (int, int) => int
becomes
someFunc: (option(int), option(int)) => option(int)
Infixes create easier to read code that looks almost like a regular function call someFunc(param2, param2)
someFunc <$> param1 <*> param2
But restricting infixes means they have to be rewritten like this.
apply(map(someFunc, param1), param2)
Infixes create easier to read code that looks almost like a regular function call
someFunc(param2, param2)
someFunc <$> param1 <*> param2
But restricting infixes means they have to be rewritten like this.
apply(map(someFunc, param1), param2)
The solution for the moment is pipe:
someFunc->map(param1)->apply(param2)
Whether it's better or worse is the entire debate around this feature. I personally agree the infix is nicer once you get used to it, I prefer both the symbolic nature and the lack of brackets required. But all three should compile to the same JS.
I would also like to add that this is a standard thing supported in F#, Haskell, Reason., Ocaml, and many other functional languages, so it’s not just some esoteric domain specific use of infixes.
Since the -> syntax works almost the same was as an infix (and can be defined as an infix) I don’t think it’s that much of a mental leap for newcomers to learn and parse infixes. Plus they’d be learning well established paradigms.
Thanks! Chris Creative Consultant
From: Andrew Herron @.> Sent: Thursday, October 7, 2021 9:39:12 PM To: rescript-lang/syntax @.> Cc: chrischen @.>; Comment @.> Subject: Re: [rescript-lang/syntax] Infix operator support (#440)
Infixes create easier to read code that looks almost like a regular function call someFunc(param2, param2)
someFunc <$> param1 <*> param2
But restricting infixes means they have to be rewritten like this.
apply(map(someFunc, param1), param2)
The solution for the moment is pipe:
someFunc->map(param1)->apply(param2)
Whether it's better or worse is the entire debate around this feature. I personally agree the infix is nicer once you get used to it, I prefer both the symbolic nature and the lack of brackets required. But all three should compile to the same JS.
— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/rescript-lang/syntax/issues/440#issuecomment-938292543, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAA2YPWM7VB2H7DF5DD6DSLUFZKVBANCNFSM46Y3J26A. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
I tried to trick it by writing the operator in an OCaml file :)
Distrib.ml
type 'a t = ('a * float) array
let pure v = [| (v, 1.0) |]
let uniform vals =
let len = vals |> Array.length |> float_of_int in
vals |> Array.map (fun v -> (v, 1.0 /. len))
let map f v = v |> Array.map (fun (v, c) -> (f v, c))
let bind ma mf =
ma
|> Array.map (fun (v, c) ->
mf v
|> Array.map (fun (v', c') -> (v', c *. c')))
|> Array.to_list
|> Array.concat
module Syntax =
struct
(* let ( let+ ) = map *)
(* let ( let* ) = bind *)
let ( >>= ) = bind
end
And use it from from ReScript
let foo = () => {
open Distrib.Syntax
let d6 = [ 1, 2, 3, 4, 5, 6 ]->Distrib.uniform
d6 >>= (num => Distrib.pure (num < 4))
}
But I get a Syntax error :)
Sadly pipelines are not a cure for monadic syntax. See:
let chance_of_seven = () => {
open Distrib
let d6 = [1, 2, 3, 4, 5, 6]->uniform
d6->bind(firstRoll =>
d6->bind(secondRoll => pure(firstRoll + secondRoll === 7))
)
}
Note: Infix >>=
wouldn't help here either. I'd love to have let*
syntax. But as far as I can tell even the OCaml compiler coming with rescript doesn't have it
yes, because ReScript doesn't have infix they can't be defined or used. The translation to use those functions right now is \">>="(d6, num => Distrib.pure(num < 4))
.
Note: Infix
>>=
wouldn't help here either. I'd love to havelet*
syntax. But as far as I can tell even the OCaml compiler coming with rescript doesn't have it
Indeed. It's based on 4.06, let*
was added in 4.08.
The rescript-lang/syntax repo is obsolete and will be archived soon. If this issue is still relevant, please reopen in the compiler repo (https://github.com/rescript-lang/rescript-compiler) or comment here to ask for it to be moved. Thank you for your contributions.
Implement parsing of operator tokens for value bindings and value description without escaping.