13 ms·
Programming a space invader in OCaml and OpenGL: lessons learned
- pjmlp 7y agoThe underlying OCaml naturally. Having learned ML via Objective Caml's predecessor, Caml Light, ReasonML seems to be just sugar coating for those with aversion to ML classical syntax.
- hellofunk 7y ago> ReasonML seems to be just sugar coating That’s exactly what it is, no secret about that, that’s the goal of that project.
- pjmlp 7y agoWhich begs the question why not learn the real deal, instead of adding another layer to debug. Programing isn't poetry.
- sshine 7y agoYou could say the same thing about Erlang and Elixir. Or Java and Kotlin / Scala. Depending on how well an alternative syntax is requested and adopted by the existing ecosystem surrounding the particular VM, YMMV. Without knowing, I think you get quite different answers in each case.
- pjmlp 7y agoI not only could, I say so. Focus on platform languages and you always win long term.
- jherdman 7y agoBecause sometimes the layer on top can express ideas more succinctly. A classic example is CoffeeScript's fat arrow syntax. It expressed a pattern in JavaScript we didn't, at the time, have a shorthand for. Example: https://coffeescript.org/#fat-arrow https://coffeescript.org/#fat-arrow
- pjmlp 7y agoAnd now it is dead, leaving behind a pile of code to rewrite in next cool toy.
- throwaway894345 7y agoIn fairness, it's dead because it was shitty and made most things harder, and the things it did improve JS copied. If OCaml fixes its syntax, then we won't have any need for Reason.
- pjmlp 7y agoThere isn't anything to fix.
- throwaway894345 7y agoIf you were right OCaml wouldn't be the only language with a popular syntax veneer.
- erichocean 7y agoTypeScript says hi.
- staticassertion 7y agoTypescript makes virtually no changes to JS syntax, except what's necessary to support types.
- erichocean 7y agoTypeScript classes, constructors and enums say hi. Talk about moving the goalposts...
- 7y ago
- toolz 7y agoI disagree, code is for and by humans. There are likely very real runtime consequences to having code that is "ugly", because the next human to touch it will value it less and do a suboptimal job. Of course all of this is highly subjective, but my understanding is that it's important to consider if you want highly successful projects.
- Gene_Parmesan 7y ago> code is for and by humans I think this is very much domain dependent. Generally the more important efficiency is, the less I find this to be true. And really, code is always for the machine at the end of the day. Additionally, if an added code layer makes the code more difficult to debug, that's also making the code worse for humans. Note I'm not arguing for or against whether that's happening in the case of OCaml/ReasonML, just making the point.
- sshine 7y ago> code is always for the machine at the end of the day On the other hand, code is read much more than it is written. You may also regard efficiency as a necessary evil if the cost is readability. Ultimately the winning strategy in this regard is achieving "free abstraction", making code that is both readable and efficient. Different languages aim at this. C++ has been best at this for most of history. Haskell and Rust are competing at this now as well. OCaml isn't exactly efficient because of free abstraction, but because of its extremely simple translation strategies. OCaml's "flambda" compiler extension wasn't released as stable until 4.03 (2016), which means that before that, very little high-level transformation was happening. My experience is that OCaml programmers care about low-level optimization, for good and for bad. For example, in this StackOverflow response there are two examples of a function 'partialsums': https://stackoverflow.com/questions/37694313/make-ocaml-function-polymorphic-for-int-lists-and-float-lists/37710287#37710287 https://stackoverflow.com/questions/37694313/make-ocaml-func... The one that Jeffrey Scofield provides is essentially more efficient because the accumulated value is a list, just like the end result, whereas my solution accumulates a tuple, which means every iteration of the fold involves boxing and unboxing that tuple. An optimizing compiler working at a higher level of abstraction might figure that out and re-use the memory of the tuple, but no sir.
- pcwalton 7y agoBecause people who know other programming languages, but not ML, might want to read your code, and it's nice if it looks familiar to them.
- pjmlp 7y agoThat is how languages like Go get designed, pour souls not able to spend some time learning.
- pcwalton 7y agoI wish Go had been a reskin of OCaml.
- terminaljunkid 7y agoThat is nowhere near their goals. Maybe if Go didn't start as a hobby project inside Google, then they /might/ even have seen some opportunity in Ocaml / Standard ML, but now that Go exists, and has a quite good toolchain, the incentive is low. Go and its foundations are radically different from a FP language like OCaml though.
- hajile 7y agoThe "real deal" here is Ocaml. It's not the most complex syntax in existence, but I'd say it's easily the most complex ML language in existence.
- throwaway894345 7y agoIf it works properly there isn't another layer to debug (and anyway, one has to debug OCaml's syntax as it is, so it's more like trading one debug layer for another). I've never had to debug into assembly before, for example. And while syntax is normally just superficial, OCaml goes out of its way to be obscure and I don't have time for that. Especially with all of its other warts (stdlib issues, crappy package management, crappy build tooling, still no multithreading, etc). I eventually just gave up. Which is too bad because the type system (absent the OO stuff) could be useful.
- deleted 7y ago[deleted]
- msla 7y agoProgramming is expressing programmer intent to the greatest extent possible given technological constraints. Sometimes, that's moving from machine code to assembly language[1]; sometimes, that's building a declarative language to express some specific logic. Finding new ways to preserve programmer intent in machine-checkable ways (that is, not just by adding comments) is one of the consistent goals of programming language design. [1] Yes, humans used to write machine code. By hand. Computers were for serious work, not mere clerical tasks such as translating mnemonic order codes to binary and doing address arithmetic.
- pjmlp 7y agoProgramming is delivering a solution that solves someone needs, typing +. or + makes zero difference solving their needs.
- mhd 7y ago> Programing isn't poetry. First time I've heard a C-like syntax described as "poetic".
- dean177 7y agoThere is no layer above, it’s not like coffeescript which compiles to another language. It’s literally an alternative syntax.
- pjmlp 7y agoSure it does, unless there is a ReasonML native compiler with its own ecosystem now.
- k__ 7y agoTrue. But the accumulation of @-signs, for example, seems to be a bit much.
- zem 7y agoreason isn't another layer, it's an alternate syntax. it doesn't compile via translation to ocaml code; both reason syntax and ocaml syntax compile to the same thing.
- baddox 7y agoNeither one is more real than the other and you really shouldn't need to do any debugging unless there are bugs in the ReasonML parser (and you could just as easily run into a bug with the Ocaml parser, but I suspect both are very unlikely).
- amw-zero 7y agoJordan Walke, the creator of Reason (also the creator of React) said that syntax is unfortunately very important, because psychologically people want something familiar. I think syntax is totally superficial, but I’m also a human who interacts with other humans. And they do not think it’s superficial. The talk where he says this: https://youtu.be/5fG_lyNuEAw https://youtu.be/5fG_lyNuEAw
- jimbokun 7y ago> ReasonML seems to be just sugar coating for those with aversion to ML classical syntax. So it's the Elixir to Ocaml's Erlang?
- firethief 7y agoElixir is a different language for the Erlang VM, but Reason is just a different syntax for the OCaml language. There's a 1:1 correspondence between their ASTs, and even a tool to convert between them.
- yawaramin 7y agoThat's one of the main ideas, certainly. The thesis is that there are a ton of people who would take one look at the ML syntax and go back to their Java/C#/JavaScript, not realizing there's more to it. But with Reason syntax (which btw was designed by the creator of Merlin), they would take another deeper look. For people like you and me, we like the ML syntax and don't have too much need for a new one. But for many others, this may be the only way they will ever even decide to look at an ML. And hey–if after that they decide that they actually like the ML syntax better–well that's one of the 'secret' goals of Reason.
- sweeneyrod 7y agoReasonML is just an alternative syntax for OCaml. Often people use "ReasonML" shorthand for "ReasonML, converted to OCaml, compiled to Javascript with BuckleScript" and "OCaml" for "OCaml compiled natively" but it's perfectly possible (and actually really easy) to use OCaml with BuckleScript and Reason natively. Also note that despite the "O" in the name, OOP in OCaml is rare (for instance, there isn't any in the code in the article).
- juliendemangeon 7y agoYou're right! The toolbox is far better too
- elcapitan 7y agoWhat's the state of using Reason natively? Last time I checked all the documentation and examples where towards the reason/js/react ecosystem. Are there any good native code projects written in Reason to look at for reference?
- sweeneyrod 7y agoPeople don't do it much, but if you're using the most popular build system (dune) you can replace your .ml files with .re ones and it will Just Work. So you can use OCaml projects for reference (I think anyone who's doing Reason should have a vague grasp of OCaml syntax, it's not really that different).
- firethief 7y ago> I think anyone who's doing Reason should have a vague grasp of OCaml syntax, it's not really that different Especially if you're targeting native, so all your dependencies are written and documented in OCaml syntax.
- baddox 7y agoAren't the Ocaml and ReasonML syntaxes so similar that you can effectively convert both directions and still end up with clean idiomatic code? That has seemed to be the case when I've played around with the ReasonML, and if it's the case, then which one you choose to write is very much arbitrary. Heck, you could even write one syntax locally and then automatically convert to the repo's preferred syntax when you commit your code.
- alharith 7y agoI am confused by this article. It went an entirely different direction based on the question proposed. It was all entertaining, nonetheless, but besides some passing comments to Reason’s documentation being better, the question does not seem to be explored much by this article. It’s a good article and should be renamed to maybe “Getting started with OCaml and OpenGL”
- juliendemangeon 7y agoYou're absolutely right. I wanted to justify my exploration by way of comparison between ReasonML and Ocaml. The title ("Programming A Space Invader In OCaml and OpenGL: Lessons Learned") still fits with the content, don't you think?
- alharith 7y agoI see that now, yes I do. I think maybe the headings and subheadings are also throwing me off as well. I wasn't sure if I was reading one of those types of blogs that have a continuous feed of articles on one page.
- kingkonz1 7y ago> it is very complicated to install the base stack to develop in OCaml I'm not sure why the author decided to use such a complicated setup using Make and Docker. They could have just ran `opam switch create 4.09.0`, which would have created the compiler, then `opam install ...` for the dependencies. Still, an interesting article. I wouldn't recommending using OCaml/ReasonML for gamedev since getting it to work with Windows is pretty much impossible.
- srpablo 7y agoWhile I didn't try to use Docker (though we did use the same pxhere image :-p), I also struggled to get a productive setup of OCaml. Getting a switch running wasn't the hard part, it was making the environment suitable for real project work. I had a set of Make targets in mind (test, build, shell), some language dev features I wanted (jump to definition, type of expression under cursor), and some properties of the project (pinned dependencies) such that it took a fair bit of fiddling with dune/opam to get it working https://morepablo.com/2019/08/fresco-jesus-ocaml-setup.html https://morepablo.com/2019/08/fresco-jesus-ocaml-setup.html I find OCaml really enjoyable once I got going, but I do think the initial setup is a major barrier to larger adoption. I think a post on howistart.org might be useful, but it'd probably be polarizing since most functions have two major ways of doing it (Jane Street vs. not, Lwt vs. Async, etc.).
- yodsanklai 7y agoI agree it's quite annoying to set up an OCaml project, and all the Jane Street stuff makes it even more confusing for newcomers. But to be fair, it may be the case with other languages as well. I recently tried to learn some Javascript, and I spent some time understanding the tooling and package management (npm/yarn, bundling, transpiling, node vs browser, difference between javascript versions).
- nickserv 7y agoModern JavaScript is a major pain to set up, but the difference with other languages is that for some things it's the only language available.
- adamnemecek 7y agoBetween reasonml and elm which one should I pick?
- weavie 7y agoIf you've not used an ML before, start with Elm. Once you feel you have that sussed - it shouldn't take too long - pull up ReasonML and give it a go. Use the Bucklscript-Tea library - the architecture will be familiar from Elm. Then give Reason-React a go. Once that itch has been scratched move on to PureScript for a whole new rabbit hole to fall down.
- adamnemecek 7y agoI mean I'm familiar with ml and haskell, I'm more interested in what's the best platform for building things. The language itself is only a part of the equation.
- azangru 7y agoI believe Reason is more practical (easier FFI), but as for building things, at this point it's probably Typescript :-) Reason still hasn't had its async story ironed out, and has poor support for Unicode[0] [0] "ReasonML strings are encoded as UTF-8 and not compatible with JavaScript’s UTF-16 strings" (from https://2ality.com/2017/12/basic-types-reasonml.html https://2ality.com/2017/12/basic-types-reasonml.html)
- yawaramin 7y ago> Reason still hasn't had its async story ironed out, Reason's async story is pretty simple: use promises until the let-syntax (like generalized do-notation) lands, then use that. > "ReasonML strings are encoded as UTF-8 and not compatible with JavaScript’s UTF-16 strings" Unfortunately this is inaccurate, and you left out a significant detail from the article. Let's go point by point here: - Reason strings are not encoded as UTF-8, in fact they aren't encoded at all. - But, when targeting JavaScript using the BuckleScript compiler, strings can contain Unicode characters and use the JavaScript runtime's support for Unicode. - This is not a short-term workaround, but the intended solution.
- hajile 7y agoReasonML is adversely affected by it's Ocaml base if anything. StandardML would have been a much better base (they went with Ocaml because it was a lower-effort to implement and Facebook has a lot of Ocaml devs). The first bad part is that Ocaml does not have a language spec. The implementation is the spec. This puts them at the whim of the Ocaml devs with no other options. SML is a standard with several good implementations. Ocaml requires different operators for float and integer arithmetic. SML assumes an integer type unless you include a decimal. Both need to be replaced with module typeclasses (and both are working in that direction). For SML though, your existing code can continue to just work as it did before while Ocaml will be left with lots of `+.` or `*.` operators everywhere. Another mistake that bleeds through is mutable strings. This is an outgrowth of all arrays being mutable. Immutable strings allow efficient representation as ropes instead of normal arrays (along with other optimizations that are good for GC'd languages). SML has immutable strings and vectors along with arrays (which you can still use as mutable strings of characters if you need them). For their React-like goal though, Ocaml's lack of anonymous record types is the absolute worst. In SML, I can just type up a record and pass it in (no type definitions required). When passing in stuff to a component, you have to have all these named arguments. In SML, I'd just pass an anonymous record and destructure it in the function -- Just like in Javascript, but with types behind the scenes to keep everything straight. Writing a custom parser for Babel like typescript or coffeescript have done would have been better for the language design and independence.
- lindig 7y ago> Another mistake that bleeds through is mutable strings. OCaml strings are immutable by default since OCaml 4.06.
- vphantom 7y agoFYI strings are now immutable in OCaml. It was a compiler option starting with 4.02 and it has become enabled by default since 4.06.
- hajile 7y agoThat's nice to know. On the flip side, that's not nice for interaction between older code that wants to mutate and newer code that wants to "copy". If the "copy" code is actually copying all the time behind the scenes (something it has to do if you are compiling with mutable strings for backward compatibility with the rest of your codebase), that's a huge performance hit.
- cpursley 7y agoMarmelab makes the pretty awesome react-admin library for autogenerating admin interfaces: https://github.com/marmelab/react-admin https://github.com/marmelab/react-admin I'd love to see an official Marmelab adapter so I can build my admin interfaces with ReasonML.
- Kmaschta 7y agoWe already have hard time migrating it to TypeScript :p How such an adapter might work?
- vzaliva 7y agoThis article title and conclusions are misleading. It shows how to write a simple game in OCaml and then proceeds to conclude that ReasonML is better. I would expect the author to have the same game implemented in ReasonML for comparison to show us why. Otherwise, it is not very convincing.
- gameswithgo 7y agohaving done some OCaml and F#, where F#’s syntax is more like reason, i think it is pretty clear that OCaml is a fascinating language but what does impose some weird syntactic work that both reason and f# relieve you of. probably to someone sufficiently used to ocaml it doesn’t matter but it can hurt adoption
- sdegutis 7y agoI always thought ReasonML was just a more JavaScript-ish syntax on top of OCaml, not necessarily better but just different. In what ways is it an actual improvement?
- nv-vn 7y agoI don't see how you can say F#'s syntax is more like Reason. OCaml and F# have nearly identical syntax for the core language, with the few differences being: 1) places features diverged 2) modules 3) F#'s "light" syntax mode None of these really seem like Reason at all. Do you have any specific places where they're similar?
- dang 7y agoWe've changed the title to that of the article, as the site guidelines ask (https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html). Submitted title was "Is ReasonML good by itself or the underlying OCaml the source of awesomeness?"
- SkySkimmer 7y ago>Even though it is known for its robustness and its large standard library I thought the ocaml stdlib was relatively small though?
- rwmj 7y agodnf install ocaml ocaml-lablgl-devel ? Anyway here's a toy game I wrote in GL + ODE + OCaml years ago: https://github.com/fccm/OCamlODE/blob/master/examples/katamari.ml https://github.com/fccm/OCamlODE/blob/master/examples/katama...
- ernst_klim 7y ago> I choose a more undisclosed tool (obuild) because of its simplicity and its brief documentation > And although some tools exist to make our life easier, they are poorly documented Seems like author choose something poorly documented. Dune build system [1], opam [2] and esy [3] package managers are very well documented. [1] https://dune.readthedocs.io/en/stable/ https://dune.readthedocs.io/en/stable/ [2] https://opam.ocaml.org/doc/ https://opam.ocaml.org/doc/ [3] https://esy.sh/docs/en/what-why.html https://esy.sh/docs/en/what-why.html
- fhcoso 7y agoInteresting but why talking at the end about F#, Scala and not Haskell (general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation) wish is more old and mature than OCaml and F#: - Haskell: 1990 - F#: 2005 - Scala: 2004