OCaml Syntax Sucks (2016)
xahlee.info
OCaml Syntax Sucks (2016)
1–10 of 140 posts
Re: OCaml Syntax Sucks (2016)
#2Re: OCaml Syntax Sucks (2016)
#3I want to like OCaml, but the tooling isn't great and async operations require a library to work for some reason. I tried f# but if you want to do async operations there, you have to do them in these even weirder "computation blocks" with this annoying ! Syntax. I've found that the best way to write ML family programs is to let an imperative language handle IO and then write any more mathematically or logically compl…
I found F# to be more pleasant to work with async than C# (which is already a breeze). It is true that you still have to define 'task' (or 'async' if you want to use Async CEs) but it is generally there for a reason. I don't think it's too much noise:
let printAfter (s: float) = task {
let time = TimeSpan.FromSeconds (float s)
do! Task.Delay time
printfn $"Hello from F# after {s} seconds"
}Re: OCaml Syntax Sucks (2016)
#4I want to like OCaml, but the tooling isn't great and async operations require a library to work for some reason. I tried f# but if you want to do async operations there, you have to do them in these even weirder "computation blocks" with this annoying ! Syntax. I've found that the best way to write ML family programs is to let an imperative language handle IO and then write any more mathematically or logically compl…
Some F# articles are outdated - they predate F# 6 which added task { } CE which simplifies asynchronous code that interacts with .NET's standard library. I found F# to be more pleasant to work with async than C# (which is already a breeze). It is true that you still have to define 'task' (or 'async' if you want to use Async CEs) but it is generally there for a reason. I don't think it's too much noise: let printAfter…
let async printAfter (s: float) =
let time = TimeSpan.FromSeconds (float s)
await Task.Delay time
printfn $"Hello from F# after {s} seconds"
and then printAfter is called with `await` as well. I'm sure there's some FP kind of philosophy which prohibits this (code with potential side effects not being properly quarantined), but to me it just results in yet more purpose-specific syntax to have to learn for F#, which is already very heavy on the number of keywords and operatorsRe: OCaml Syntax Sucks (2016)
#5Earlier quoted context omitted.
Some F# articles are outdated - they predate F# 6 which added task { } CE which simplifies asynchronous code that interacts with .NET's standard library. I found F# to be more pleasant to work with async than C# (which is already a breeze). It is true that you still have to define 'task' (or 'async' if you want to use Async CEs) but it is generally there for a reason. I don't think it's too much noise: let printAfter…
I dislike that there's a kind of sub-syntax specifically for async. I like how C# converts `await` into the necessary calls. In this code I think it would look better to simply have: let async printAfter (s: float ) = let time = TimeSpan.FromSeconds (float s) await Task.Delay time printfn $"Hello from F# after {s} seconds" and then printAfter is called with `await` as well. I'm sure there's some FP kind of philosophy…
'async'-annotated methods in C# enable 'await'ing on task-shaped types. It is bespoke and async-specific. There is nothing wrong with it but it's necessary to acknowledge this limitation.
let!, and!, return!, etc. keywords in F# are generic - you can build your own state machines/coroutines with resumable code, you can author completely custom logic with CEs. I'm not sure what led you to believe the opposite. `await Task.Delay` in C# is `do! Task.Delay` in F#. `let! response = http.SendAsync` is for asynchronous calls that return a value rather than unit.
In the same vein, seq is another CE that is more capable than iterator methods with yield return:
let values = seq {
// yield individual values
for i in 1..10 -> i
// yield a range, merged into the sequence
yield! [11..20] // note the exclamation mark
}
Adding support for this in C# would require explicit compiler changes. CEs are generic and very powerful at building execution blocks with fine control over the behavior, DSLs and more.Reference: https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
Re: OCaml Syntax Sucks (2016)
#6Earlier quoted context omitted.
I dislike that there's a kind of sub-syntax specifically for async. I like how C# converts `await` into the necessary calls. In this code I think it would look better to simply have: let async printAfter (s: float ) = let time = TimeSpan.FromSeconds (float s) await Task.Delay time printfn $"Hello from F# after {s} seconds" and then printAfter is called with `await` as well. I'm sure there's some FP kind of philosophy…
It's the other way around. 'async'-annotated methods in C# enable 'await'ing on task-shaped types. It is bespoke and async-specific. There is nothing wrong with it but it's necessary to acknowledge this limitation. let!, and!, return!, etc. keywords in F# are generic - you can build your own state machines/coroutines with resumable code, you can author completely custom logic with CEs. I'm not sure what led you to be…
Re: OCaml Syntax Sucks (2016)
#7Earlier quoted context omitted.
I dislike that there's a kind of sub-syntax specifically for async. I like how C# converts `await` into the necessary calls. In this code I think it would look better to simply have: let async printAfter (s: float ) = let time = TimeSpan.FromSeconds (float s) await Task.Delay time printfn $"Hello from F# after {s} seconds" and then printAfter is called with `await` as well. I'm sure there's some FP kind of philosophy…
It's the other way around. 'async'-annotated methods in C# enable 'await'ing on task-shaped types. It is bespoke and async-specific. There is nothing wrong with it but it's necessary to acknowledge this limitation. let!, and!, return!, etc. keywords in F# are generic - you can build your own state machines/coroutines with resumable code, you can author completely custom logic with CEs. I'm not sure what led you to be…
I would disagree. If you need to have a bespoke set of syntax, then something is not integrated where it should be. The language design should not be such that you are writing things differently, depending on the paradigm that you're handling. That's not something that occurs in every language, so it isn't essential that it exists.
We can acknowledge the differences in a way that alerts the programmer, without forcing the programmer to switch syntaxes back and forth when moving between the paradigms. async/await is one method, Promises another, etc. A different syntax is a much, much higher cognitive load.
Re: OCaml Syntax Sucks (2016)
#8Re: OCaml Syntax Sucks (2016)
#91. there’s no marker to indicate the end of let scopes
2. functions are bound with the same syntax as constants
He asserts that this is confusing. In practice - for the many issues I have with Ocaml! - neither of these are actual issues, in my experience, once code formatting is applied.
An actual serious problem with Ocaml’s syntax is that matches don’t have a terminator, leading people to mess up nested matches frequently. Pair that with the parser’s poor error reporting/recovery and things can become unpleasant quickly.
Re: OCaml Syntax Sucks (2016)
#10I want to like OCaml, but the tooling isn't great and async operations require a library to work for some reason. I tried f# but if you want to do async operations there, you have to do them in these even weirder "computation blocks" with this annoying ! Syntax. I've found that the best way to write ML family programs is to let an imperative language handle IO and then write any more mathematically or logically compl…
Rephrased: ocaml is so flexible that async can be implemented as a library with no special support from the language.
This is the beauty of ocaml (and strongly typed functional languages more broadly)