11 ms·
Why Go? Use Racket
- nine_k 12y agoNo. Because static typing. However much Go's type system might lack some means of expression, the type system is there, and it prevents many bugs that can easily crop up while using a dynamic language. I'd rather say 'use OCaml' or 'use F#' or even 'use Haskell'.
- wtetzner 12y agoOr 'use Typed Racket'.
- nine_k 12y agoUnfortunately, the article in question did not mention words 'typed' or 'static' at all. I didn't know about Typed Racket; I suppose it might be a kind of gradual / optional typing somehow simila to what Clojure has.
- michaelsbradley 12y agoClojure's gradual typing system is heavily inspired by Typed Racket, which preceded it. https://twitter.com/ambrosebs/status/262387983339098113 https://twitter.com/ambrosebs/status/262387983339098113 For more information, see Ambrose Bonnaire-Sergeant' dissertation: A Practical Optional Type System for Clojure https://cloud.github.com/downloads/frenchy64/papers/ambrose-honours.pdf https://cloud.github.com/downloads/frenchy64/papers/ambrose-...
- rdtsc 12y agoOr Clojure or Erlang. Funny enough out of "functional" languages those have probably just as much (or even more) been used to develop distributed, fault tolerant systems than F# or Haskell. Just saying. BTW both Clojure and Erlang allow a form a gradual typing. From personal experience. I've used both static (C#, C++, Java) and dynamic typing (Python, Erlang), and have to say, the prevents-many-bugs excuse as the main problem with dynamic types just wasn't true. Maybe my code is more complicated and dealing with distributed state, consistency, and protocols but what what kills everything is usually logic errors, network failures, files not being there, misconfiguration, segfaults, user-after-free, and the most evil ones, shared global states in a concurrent shared-heap environment. Things like "oh I expected an int but got a string" are pretty trivial and easy discovered. Moreover, in a recent service I implemented. I did in Python and I believe the faster development time and less code to write in general, gave me time to write better integration tests that exercises and covered the code a lot better. I would have had to write the tests anyway, even if this was written in Haskell. Perhaps static typing helps a lot more in large code bases. Think of a large game, or a CAD application or some huge C++ back-end. But, if you buying into the whole micro-services fad, well, you shouldn't have large code bases if you can help it. Another big motivation for types, which I think most people have in mind when they pick a strongly typed language is performance. Usually static typing and a very large performance increase would go hand in hand. Now with the effort put into v8 and PyPy we see that gap getting smaller.
- lomnakkus 12y ago> Or Clojure or Erlang. Funny enough out of "functional" languages those have probably just as much (or even more) been used to develop distributed, fault tolerant systems than F# or Haskell. Just saying. (I generally agree with the gist of your comment, I think. This just stuck out.) I don't believe Clojure belongs in that class (as "proven" for writing reliable software), but whatever. If you want truly reliable software and have the budget, then you just need to throw process at the problem -- it doesn't matter much which language you use. Several (if not all) the Mars landers were programmed in C -- with very few critical flaws experienced/discovered[2]. The Ericsson switches that achieved previously-unheard-of reliability were programmed in Erlang, but they used process and a huge number of engineers to achieve that. (Plus they're mostly stateless and so can just reset if they do it fast enough and don't lose important state when doing so.) For large-scale software which has to evolve fast, I belive strong type systems do win out. It's not so much that they prevent bugs which could be caught by test suites, but having a strong type system means that you can be certain that there are a lot of tests that you actually will never have to write or, more importantly, rewrite as the system evolves. There have been actual studies which may be of interest[1], but even if I'm on the "winning" side, I don't think I would put too much stock in the methodology/analysis of this particular study. (E.g. concluding that JavaScript suffers from few concurrency bugs relative to other languages is kind of being oblivious of the fact that JS is single-threaded (semantically) and that all the other languages in the comparison permit "real" concurrency/parallellism, and that it should thus perhaps be excluded from the category or at least treated separately.) [1] http://macbeth.cs.ucdavis.edu/lang_study.pdf http://macbeth.cs.ucdavis.edu/lang_study.pdf [2] https://www.usenix.org/conference/hotdep12/workshop-program/presentation/holzmann https://www.usenix.org/conference/hotdep12/workshop-program/... (Sorry, references out of order because edited-post-facto)
- sheepmullet 12y agoIn the study you linked to Clojure code is basically as bug free as Haskell and Scala code and Erlang code isn't far behind.
- 12y ago
- mistobaan 12y agoshouldn't be: Why Go? (Use (Racket))
- chc 12y agoThat looks like you want to use the result of Racket, rather than use Racket itself.
- jamra 12y agoI'm sorry you lost me after your outrageous claim that one must learn everything about the standard types of Go before one can program effectively. You should know about how your types are passed around if you are using any language. The example given was arrays in Go. Arrays are passed by value, but slices (pointers to arrays) are passed by reference. This is very simply described in the Effective Go reading. It's not a hard concept. I don't like you writing off Go with that example. It sounds like you made an emotional decision against the language and are grasping for logical reasons to support your already made decision. How many people programming with Go pass arrays around? It's an easy lesson to learn.
- nulltype 12y agoI think slices are actually passed by value. From "Effective Go": "We must return the slice afterwards because, although Append can modify the elements of slice, the slice itself (the run-time data structure holding the pointer, length, and capacity) is passed by value."
- jamra 12y agoYou are absolutely correct. To borrow form another's comment, https://play.golang.org/p/VOUJI88PNj https://play.golang.org/p/VOUJI88PNj The slice, however, is a small structure to pass to a function in that you are not performing a copy of each individual element in the slice.
- eloff 12y agoThere are many valid criticisms of go, but the one presented in this article make no sense. Or maybe only make sense if you're a huge dynamic languages fan and can't stomach static typing. Personally, as someone who used to be a huge fan of dynamic languages like Python, I've sobered up as I've grown older and had to fight with large python and JavaScript code bases. A compiler that is fast with clear error messages is tremendously valuable.
- Dewie 12y agoIf using dynamic typing like Python's is being drunk, then at least Go is like being tipsy - not quite sober, but quite functioning.
- tedsuo 12y agoThe OP's complaint about Go's type system seems to mainly be that memory allocation is explicit. Go is always "pass by value", and it's true that I've watched developers struggle to grasp the full ramifications of what that means regarding memory usage. But not understanding the subtlety of memory allocation usually means your programs will simply run slower and consume more memory. It does not usually mean that your programs will run incorrectly. Given that the OP mentions that they find the slower, more expensive execution of racket programs to be an acceptable trade-off, I'm surprised that they have a problem with this. Personally, I prefer running in a language that allows me to reason about the memory allocation explicitly. I'd only prefer to give that up in favor of a declarative language that could compute the optimal execution for me. Unfortunately that language is a bit of a unicorn for general purpose programming.
- lucio 12y agoIn Go you can pass a pointer, and a pointer to a pointer. I understand both cases are usually called "pass-by-reference". If you call "pass-by-value" to passing a pointer, then the notion of "pass-by-value" and "pass-by-ref" are not very useful.
- tedsuo 12y agoIf what you are passing is a pointer, then the value of the pointer (an integer) is copied. So pointers are passed by value. "Pass by reference" means that the runtime will convert what looks like an instruction to copy a value (such as a data structure) into an instruction to copy only the address. Go has no such concept. You cannot make a new value that is a "reference" to another value. If you make a new variable that takes a value, that variable allocates a new block of memory the size of that value. Assigning a value to the variable (or passing a value to a function) makes a copy of the value into the new memory address. You can make a "reference" only by explicitly making a pointer and copying the address of another object. "Pass by reference" languages treat everything as a pointer by default, forcing you to make a copy operation when you do not want this behavior. This may seem like an equivalent programming model, and possibly simpler because this pointer business if confusing at first. However, basic concepts such as a call stack or an array of values can no longer be expressed easily, because with "pass by reference" languages you have removed the concept of a value from the language. So pass-by-reference languages can lead to confusion in large programs, even if they seem simpler at first. Basically, go is "pass by value" because the language forces you to always be explicit about when you are copying an entire value, and when you are only copying a pointer.
- inconshreveable 12y agoOf the complaints you can make about Go's type system (and there are many), being too complex is not one of them.
- dhemmerling 12y agoIn the comments he says he changed his mind about Go, and the necessity of the efficiency gain over Racket. So there's some confusion apparently. https://cxwangyi.wordpress.com/2012/07/22/why-go-use-racket/#comment-871 https://cxwangyi.wordpress.com/2012/07/22/why-go-use-racket/...
- vvpan 12y agoIt's a chicken and egg problem, but the real reason for me to use Go vs Racket is that learning the former will further my career significantly, while latter won't at all. Sad, but true.
- michaelsbradley 12y agoIt depends. Learning Racket and the design methodology taught by Felleisen, et al. could help you become a better programmer in general, and thus significantly further your career. How to Design Programs, Second Edition http://www.ccs.neu.edu/home/matthias/HtDP2e/ http://www.ccs.neu.edu/home/matthias/HtDP2e/
- kod 12y agoI'd certainly be much more likely to hire someone who had worked through How To Design Programs
- vvpan 12y agoSure, I agree. But the impact is much less direct. Most interviews go like this: "Have you worked with Angular?". And you just don't really need to be a very good programmer to have a well-paying job.
- sheepmullet 12y agoIt is incredibly sad and reflective of a broken industry. One of the major advantages of Go is that it is easy to learn for existing programmers as there are very few different abstractions/features. Yet plenty of companies are now requiring prior experience in Go, erasing most of the benefits of using Go.
- sheepmullet 12y ago...use your words... not your down votes
- fixxer 12y agoRacket's website (http://racket-lang.org/ http://racket-lang.org/) has an "explain" button by the code snippet. Is the existence of such a button perhaps a statement about the quality of the syntax?
- samth 12y agoNo, it's a statement that the developers of Racket care about explaining how things work.
- fixxer 12y agoPerhaps because they need to? Or do you find Racket as clear as other languages? Even other Lispy ones? Without trying to be insulting, I find Racket aesthetically unappealing.
- Crito 12y agoDid you even read what pops up when you hit that explain button? Sending email #lang racket ; Sending email from racket (require net/sendmail) (sleep (* (- (* 60 4) 15) 60)) ; 4h - 15m (send-mail-message (getenv "EMAIL") "Parking meter alert!" (list (getenv "EMAIL")) null null '("Time to go out and move your car.")) > "Racket comes with plenty of libraries." > "To run the example, install Racket, start DrRacket, paste the example program into the top area in DrRacket, and click the Run button. Alternatively, save the program to a file and run racket on the file." That section of the landing page is meant for people who have not been exposed to Racket before. It is meant to sell those people on the expressiveness/power of the language. The explain button is meant to explain exactly what that code snippet is meant to be demonstrating. Very few of those seem to touch on syntax at all. It seems insane to me that somebody could spin user-consciousness on a language's website as as indicative of a low-quality language.
- Dewie 12y agoI'm inclined to disagree about the distinction between pointers and values being explicit, and how that is bad - I think it might be the right decision in an imperative language that tries to be performant in a straightforward way (as opposed to language that tries to be performant by relying on compiler optimizations - that might work for certain languages). It allows you to be aware and more careful about indirection and memory layout, which obviously can buy you a lot with regards to performance. It certainly seems like the more lower-hanging fruit than what the usual advice for getting a fast programming language is - make memory management explicit/manual (though it seems that if you have pervasive manual memory management, you end up with a clear and explicit distinction between values and pointers to values anyway).
- 4ad 12y agoAuthor thinks Go's select statement has any resemblance to with epoll and kqueue. Didn't read further.
- bentronic 12y agoThat's too bad, because you missed the brilliant ending to the post, in which the author answers the question posed in the title: > P.S. As noted in [link], Racket programs build and run much slower than Go programs.
- aikah 12y agoI like crosscompilation and being able to deploy a stand alone executable without the whole sdk needed.Does racket do that?
- michaelsbradley 12y agoYes, that's possible: http://docs.racket-lang.org/raco/exe.html http://docs.racket-lang.org/raco/exe.html http://docs.racket-lang.org/raco/exe-dist.html http://docs.racket-lang.org/raco/exe-dist.html
- wtf_is_up 12y agoI may have missed in those docs any mention of cross-compilation. The first result for 'cross compile racket' is [1]. Of course that's from 2013, so maybe it changed since then. [1] https://groups.google.com/forum/m/#!topic/racket-users/LLB6oV1VsPo https://groups.google.com/forum/m/#!topic/racket-users/LLB6o...
- michaelsbradley 12y agoYou're right – I keyed in on "stand-alone executable" and not the "crosscompilation" part of the question.
- michaelsbradley 12y agoThe blog post is a couple of years old, so it's probably worth noting that PLaneT[1], mentioned by the author, has been superseded by a new Packages[2] system. PLaneT is still operating, however, and libraries hosted there can be installed with raco[3]. [1] http://planet.racket-lang.org/ http://planet.racket-lang.org/ [2] http://pkgs.racket-lang.org/ http://pkgs.racket-lang.org/ [3] http://docs.racket-lang.org/raco/index.html?q= http://docs.racket-lang.org/raco/index.html?q=
- copsarebastards 12y agoI'll come right out and say that I despise Go. It's a terrible language that ignores decades of language research and brings nothing new to the field, but has become popular due to Google hype. That said, Go -> Racket is a pretty big jump. Even though I think Go is terrible, I can at least take the time to see the problems it's solving and offer comparable languages. I suggest Rust as a Go replacement. Don't get me wrong, Racket is pretty good. It's not the Lisp I would pick (I really like Gambit Scheme) but it's at least a Lisp. But a high-level language like Racket isn't really comparable to Go. They're just in different spaces.
- kibwen 12y agoRust's and Go's strengths are very dissimilar, there's no reason to consider one as the replacement for the other without considering a dozen other worthy languages in between.
- copsarebastards 12y agoSure, if you make vague enough statements, they're hard to disprove, which might lead you to believe that what you said is correct even though you haven't made a provable or disprovable claim. There are plenty of problems where one might consider using Go or Rust. The same cannot be said of Go and Racket, or Rust and Racket. I wouldn't consider using Racket for a situation where I need high performance or low memory usage--the numbers just don't work. Likewise I wouldn't look at Go or Rust for building a data-presentation type webapp.