'RACKET' Programming Language. Say-what!? - Page 1
Forum section: electronics / general

author: GlennSprigg
author_rank: Super Contributor
timestamp: January 11, 2020, 01:35:18 pm
content: According to various lists of languages common to GitHub, the least is 'Lisp'...It's all horses for courses though, and one uses what is best suited to the task.'Lisp', (short for 'List-Processing'), is very old! 'Scheme' was/is based on it, and now'Racket' is on the forefront, and is based on 'Scheme'. Haven't heard of it ??I'm going back to roots with it now, after studying numerous sites/help. Here's a starter...https://practicaltypography.com/why-racket-why-lisp.htmlIt is extremely well structured, and everything is based on functions & expressions.Has anyone here heard of/used it?? I intend to follow up with some details & examplesif there is any interest.

author: donotdespisethesnake
author_rank: Super Contributor
timestamp: January 11, 2020, 01:59:24 pm
content: After 40 years of inventing new programming languages, most people have realised that inventing yet another language doesn't solve anything.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 11, 2020, 02:30:35 pm
content: Quote from: donotdespisethesnake on January 11, 2020, 01:59:24 pmYet they keep doing it.

author: janoc
author_rank: Super Contributor
timestamp: January 11, 2020, 03:30:41 pm
content: Racket isn't really new in any sense of the word. It is renamed (in 2010) PLT Scheme, originally from 1995! And when it comes to Lisp and its various dialects (Scheme and thus Racket are Lisp dialects), that's one of the oldest programming languages (not counting assemblers) still in use - only Fortran is older.PLT Scheme used to be a very popular teaching language for the introductory programming courses in computer science programs (it has been explicitly designed for that purpose, along with Pascal). Only much later it has been mostly displaced by things like Java and Python.Racket is actually a pretty neat if you are interested in high level programming - it is Lisp/Scheme "with batteries included" (i.e. huge set of included libraries for everything conceivable, unlike many Common Lisp distributions) similar to how Python is distributed, even including a pretty decent IDE (DrRacket) with some unique features.Actually, John Carmack (of the iD Software Doom/Quake, Oculus and Armadillo Aerospace fame) took it up when teaching his son to program and has something to say about it:https://www.itworld.com/article/2978142/why-john-carmack-thinks-racket-is-aces-for-beginning-programmers.htmlIt is a teaching-oriented language, so don't expect to program microcontrollers with it or write a high speed stock trading application in it, but what it does it does well.

author: GlennSprigg
author_rank: Super Contributor
timestamp: January 13, 2020, 12:50:11 pm
content: 'janoc' pretty much said it all !!It's not a 'new' language, but a newer 'dialect' of one of theoriginals, and now with a HUGEsubset of additional modules, greatly increasing it's power & functionality.I personally think it is great introduction tofunctional programming!!And where the lessonslearnt put you on good stead with a myriad of more 'modern' languages. A win-win to me...With say 'BASIC', (Beginners All-purpose Symbolic Instruction Code), it went way beyond the'beginners' in school, in the end, right through to .net applications still valid/powerful today!(Of course you wouldn't write a modern 'game' with it, but would generally suffice, mostly!).'Lisp', (Racket), is all about learning from square one again, about fully structured writing, ifat least as a precursor, to getting you back to, (or starting from!), structural writing & basics.It'snotre-inventing any wheel, but taking you back to what a'wheel' is/was& how it works!!I may have 'jumped-the-gun' with my original post. I'll be back after licking my woundsP.S. Consider a typical high level approach like...public class HelloWorld {public static void main(String[] args) {System.out.println("Hello world");}}In 'Racket', it's simply..."Hello World"Even a '+' sign is basically a Function call, so calculations are in 'prefix' notation like...(+ 12 4)16EVERYTHING in Lisp/Racket is anEXPRESSION!And you can intermix statements &expressions how ever many levels deep you want, like...(+ 42 (if (< 1 0) 100 200))Sorry, I shouldn't have started with this yet!

author: janoc
author_rank: Super Contributor
timestamp: January 13, 2020, 09:57:59 pm
content: Be careful - neither Lisp nor Scheme are really about functional programming. Both languages are multi-paradigm ones and will happily support imperative (heck, Common Lisp has even a GOTO equivalent! See:http://clhs.lisp.se/Body/s_go.htm#go, similar thing for Racket:https://docs.racket-lang.org/control-manual/index.html#%28form._%28%28lib._control%2Fmain..rkt%29._begin%2Fgoto%29%29), structured, object oriented or even functional style. And many others, given the macro system and the ability to define your own syntax. Especially Racket comes with several different languages included.So just because you are writing Lisp code it doesn't mean it is in a functional style (i.e. with no side effects). Lisp isn't Haskell where you don't have a choice.

author: bsudbrink
author_rank: Frequent Contributor
timestamp: January 13, 2020, 10:39:51 pm
content: Quote from: donotdespisethesnake on January 11, 2020, 01:59:24 pmFrom your mouth to God's ears (as the old saying goes). Unfortunately, there are still plenty of... <people> coming up with magic bullet, solves all the world's woes, greatest thing since sliced bread, etc languages. I'd just as soon stick with assembly, or C where some portability is required.

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 14, 2020, 02:22:59 am
content: Quote from: janoc on January 13, 2020, 09:57:59 pmAgreed.

author: wilfred
author_rank: Super Contributor
timestamp: January 14, 2020, 03:30:12 am
content: Quote from: donotdespisethesnake on January 11, 2020, 01:59:24 pmThat doesn't sound right. Which language is the one that existed before the "new" later ones added nothing more?

author: janoc
author_rank: Super Contributor
timestamp: January 15, 2020, 04:52:42 pm
content: Quote from: wilfred on January 14, 2020, 03:30:12 amLisp? Given that it is the second oldest language still in use (besides Fortran)? One can argue that Lisp has pretty much everything, even though it is likely fair to say that a lot of those features have been added only later and not from the start.However, that rant from donotdespisethesnake is just that - a rant. Programming languages are tools, the same as a multimeter or oscilloscope. Both evolve over time as we are discovering how to do things better (or worse in some cases). If someone doesn't like some language or having to continuously learn and adapt, that's really not the fault of the programming language ...And this seems pretty relevant to this Lisp discussion:

author: GlennSprigg
author_rank: Super Contributor
timestamp: January 22, 2020, 01:04:23 pm
content: Quote from: SiliconWizard on January 14, 2020, 02:22:59 amI'm sorry, but there are thousands of sites/refs that state that it IS a 'Functional' language. Eg...https://cs.uwaterloo.ca/~plragde/flaneries/TYR/https://www.bootstrapworld.org/blog/software/FunctionalLanguages.shtmletc. etc. etc.Maybe you have a different interpretation of what 'functions' mean ?Virtually everything in 'Racket' involves Functions, & Functions within Functions??There are no loose ends, with anything not declared/used within Functions.And Statements/Loops within Functions, add infinitum... fully structured/accounted.

author: brucehoult
author_rank: Super Contributor
timestamp: January 22, 2020, 04:35:44 pm
content: Quote from: GlennSprigg on January 22, 2020, 01:04:23 pmThere is no need for interpretation of what "functional programming" means.It does NOT mean programming using functions.It means programming without using assignment. You create a name with an initial value and it keeps that same value forever. You can't change it.Scheme *can* easily be used for functional programming, but it doesn't force you to.

author: janoc
author_rank: Super Contributor
timestamp: January 22, 2020, 04:49:30 pm
content: Quote from: GlennSprigg on January 22, 2020, 01:04:23 pmNo, you don't understand what I wrote. That's not the same thing as having the program composed out of functions - then C would be a functional language as well! Or rather that's only the loosest possible interpretation of the term which is rarely used these days in computer science (it was relevant in the days of Basic, Fortran and such when the concept of a function was still a pretty newfangled idea).When people talk about functional programming, they have mostly in mind a special type of functions called "pure functions". Those are functions which have no side effects, i.e. that their output depends only on their arguments (i.e. no global variables, no hidden state from some singletons - or even stuff like OS services, no mutable state). This is important because it makes certain classes of problems much easier to deal with - e.g. proving program correctness or parallelism (if there is no hidden state, there are no race conditions neither, so such functions are inherently re-entrant & thread safe, for ex.)A pure functional language is mostly an impractical academic exercise, though - in the real world we need I/O, we need to deal with the OS which has state, etc. Also some things are simply utterly inconvenient to write in a purely functional style e.g. having to pass some sort of context variable everywhere instead of having it global.Some pure functional language deal with this problem by "sweeping the (non-pure) mess under the carpet". E.g. Haskell (a purely functional language) does this with its concept of monads. Haskell's monad is essentially nothing else but fancy name (with some complex theoretic machinery behind) for wrapping the state into an opaque blob that is passed into functions that need to deal with it as an argument (think context pattern) and the rest of the code remains pure.In comparison, Scheme/Racket doesn't force you to do anything like that because it is not a (pure) functional language but a multiparadigm one (same as its daddy Lisp). You are free to declare e.g. your global variables (state - function result of a function using it doesn't depend only on its arguments) and mutate them in your code as you wish (a side effect of a function - it changes something else besides its return value). Or to wrap your OS services (e.g. a network socket) and then the result of your function will depend not only on its arguments but also the socket's state, which is controlled by the OS.That's why I have said that simply writing a Scheme program does not automatically mean that it is written in the functional style. In fact, in Racket you can pretty well write a messy, Fortran-style imperative code with no problems, even including the gotos, if you are really so inclined (just don't show it anywhere for your own sake!). The language allows it. In comparison, in pure functional languages like Haskell you would be out of luck with such approach, it is simply not possible there.Here is a good explanation of the code style difference:https://beautifulracket.com/funstacker/There are also other aspects of the functional programming style that are not automatic merely by the virtue of using a Lisp-derived language - higher order functions (functions that take functions as arguments, e.g.mapand functions returning functions), tail recursion instead of iteration (iteration inherently mutates state, which is a no-no in functional programming) and a few other things that you need to consider.

author: GlennSprigg
author_rank: Super Contributor
timestamp: January 26, 2020, 11:54:28 am
content: Thank you to 'brucehault' also, but IMAINLYthank'janoc'for his very in-depth, precise reply!!I did understand that the wording re: 'Functional Programming' and 'Programming with Functions'can cover overlapping grey areas, and in a wide variety of Languages. And after re-reading yourexcellent reply, (4 times now!), Inowunderstand everything you said, and thank you for that!One interesting aspect of 'Dr.Racket' I like, is that one has a choice at any timeline, to utilize various'flavors' of 'Racket', from Beginner through to Advanced. The idea being that at Beginner & Intermediatelevels, certain built-in Functions/Statements are not allowed, or limited, so that one doesn't get intobad habits! when coding, which can result in the type of problems/assumptions that you mention.For instance, one CAN define a 'Global' style variable/word, with the likes of...(define x 25).However, inlowerthan 'expert' mode, you cannotre-define it like now...(define x 36). It fails!But the FULL version of RacketDOESallow it! All aimed at stopping bad practices coming in.There are many other examples of such self limiting within the 'learning' versions.Thank you again, for your fantastic reply. You have helped me greatly...P.S. Your 'link' is very good!!!

author: janoc
author_rank: Super Contributor
timestamp: January 26, 2020, 02:05:05 pm
content: You are welcome and enjoy your learning experience. Lisp and (Racket specifically) are well known for the ability to define your own languages in them, thanks to the extremely powerful macro system. That's what you are seeing in DrRacket.Even if you never use functional programming or Lisp "in anger" to solve a real problem, it is always beneficial to learn a different approach to solving problems. It will make you a better programmer/engineer because it adds another set of tools to your professional toolbox.Btw, that (define x ...) doesn't work for redefining variables is normal. It is not meant to. Redefining variables is a bad practice that leads to buggy code - by redefining a variable you would be essentially saying that: "this train is a bicycle now".Define binds a symbol to a value (think declaring variable and assigning it an initial value) - i.e. declares a variable. If you try to declare the same variable again, it is an error ("identifier already defined ..."). If you want to perform an assignment (to mutate a value), there is set! instead, which works only on previously defined variables (but then see the part on mutating state and functional programming - it is a poor practice to mutate state unless there is no other way).

author: Kalvin
author_rank: Super Contributor
timestamp: January 26, 2020, 02:34:47 pm
content: For those trying to figure out how Racket compares to Clojure [Yet another Lisp-based language with higher popularity count at Github], here is one thread from Quora:https://www.quora.com/How-does-Racket-compare-to-Clojure

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 26, 2020, 04:27:38 pm
content: Quote from: brucehoult on January 22, 2020, 04:35:44 pmYup. Programming languages that allow some form of "functional programming" but don't enforce it are often called "impure functional languages".Of course those are just words... IMO, using the functional programming paradigm in an "impure" way does not really provide the benefits of functional programming, and I don't see the point. Just my opinion.I agree with the learning factor - although pure functional has relatively limited use in the real world, it's still an interesting and important thing to learn as part of your "programming literacy".Again from personal opinion, anyone really interested in functional programming should preferably take a look at the following languages: ML derivatives (such as OCaml), Haskell, Erlang. Erlang looks like a very weird beast that seems hard to tame at first sight, but I took a deeper look at it a while ago and find it actually pretty clean. It's one example of a functional PL that can be really used in real-world, industrial applications. (The list is just mine - you can of course also cite Clojure and Scala, for instance, which I just happen to not like that much.)As a very introductive part, I would also suggest taking a look at lambda calculus. It lays the groundwork of functional programming IMO.An interesting/important "feature" of a functional PL is higher-order functions. So any language that 1/ can inherently allow mutating objects and 2/ doesn't allow higher-order functions wouldn't qualify as a proper functional PL. IMO.

author: brucehoult
author_rank: Super Contributor
timestamp: January 26, 2020, 08:34:28 pm
content: Quote from: SiliconWizard on January 26, 2020, 04:27:38 pmThe problem with that is the entire *purpose* of a program is to change the state of the world, even if just by outputting an answer onto your terminal screen. In a microcontroller, you're often even more physically changing the state of the world.So impure is *necessary* at some level.But that doesn't mean it's not useful to write your program as:void loop(WorldState_t oldState){WorldState_t newState = some_pure_function(oldState);setRealWorldState(newState);loop(newState);}Then you can be 100% pure inside some_pure_function();It's also quite accepted in many communities to use non-pure programming inside an individual function if you want, as long at the interface is pure.The classic example of this in Lisp is reversing a list where you know you don't need the orignal version any more by rewriting the "next" pointers to point to what was previously the previous list item.You actually can program in a mostly-functional style in C quite well if you use a garbage collector. The Boehm–Demers–Weiser garbage collector (commonly called "Boehm") works extremely well.Modern C compilers will automatically turn tail recursion (such as in the above function) into a loop in the generated machine code.There's not much point in something as simple as that, but once you get to complex loops things are often much easier to write and understand (and prove correct) using tail-recursion.

author: magic
author_rank: Super Contributor
timestamp: January 26, 2020, 11:40:56 pm
content: Tail recursion in C is not guaranteed so by Murphy's law you will hit a case where some peculiar compiler or some peculiar compiler flags end up causing unexpected stack overflows.At least that's what people say. I never rely on tail recursion optimization in production code to avoid tempting fate.As for mixing imperative and functional code, I think I may have committed that perversion once at the uni. It wasn't really that bad. OCaml actually is a pretty decent imperative language on its own right. I wouldn't mind if C had a more OCaml-like syntax, for exampleOh, and proper algebraic types with pattern matching, please

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 27, 2020, 04:27:20 pm
content: Quote from: magic on January 26, 2020, 11:40:56 pmOf course it's not guaranteed. GCC does it past a certain opt. level (not sure which) in most trivial cases, but it's not fool-proof. Other compilers may or may not do it as well. But there is absolutely NO guarantee. As far as the compiler is concerned, it's just a possible optimization, not a feature.Quote from: magic on January 26, 2020, 11:40:56 pmIf you have a rule of not using recursion in production code, you can certainly NOT rely on this optimization to enforce it. Anyone who would should get fired.

author: brucehoult
author_rank: Super Contributor
timestamp: January 27, 2020, 06:04:07 pm
content: There are compilers for a number of other languages that need proper tail-call elimination according to their specification and that compile to C as a portable assembly language. They depend on gcc doing it. The conditions under which gcc will and will not do tail-call elimination are well documented and can be depended on.Similarly for llvm.If you use some other C compiler then of course all bets are off.

author: GlennSprigg
author_rank: Super Contributor
timestamp: January 28, 2020, 03:06:36 pm
content: Quote from: janoc on January 26, 2020, 02:05:05 pmI understand what you are saying, my friend.However, when you quoted....Btw, that (define x ...) doesn't work for redefining variables is normal. It is not meant to. Redefining variables is a bad practice that leads to buggy code - by redefining a variable you would be essentially saying that: "this train is a bicycle now".That s what I understood/meant about the limitations with the 'Lesser' versions of 'Dr.Racket'.For instance, the utilization of the likes of (let! ....) Yes, you are FORCING a new value, but in the'beginner' modes, it is not allowed. Again aimed at instilling 'good' programming styles.Thanks so much mate!!

author: frogg
author_rank: Regular Contributor
timestamp: January 28, 2020, 04:55:20 pm
content: In reality, the practical features of all lambda languages and functional programming have already been implemented in one way or another by other larger, more commercially pervasive languages.That's not to say that Lisp / Scheme / Racket are not good languages. However, it's because of the reason above that these languages are nowadays used almost exclusively for teaching purposes.

author: janoc
author_rank: Super Contributor
timestamp: January 29, 2020, 09:49:18 am
content: Quote from: frogg on January 28, 2020, 04:55:20 pmYou could be quite badly mistaken there with that argument. E.g. Lisp's macro system pretty much doesn't exist in another mainstream language. In C# you get half-assed generics, in C++ messy templates, which are pretty much a second, completely different Turing-complete language implemented inside of C++. In Lisp you have macros written in Lisp itself that work directly at the syntax tree level (because the language source code is effectively its own AST, unlike in e.g. C).That concept is very much what makes Lisp (and derivatives) so powerful and allows extending the language "from within" - e.g. you like await/async style programming? There is a library for that. You want coroutines? Serve yourself, another library implements them. Etc.Can you do without it? Sure, there are tools for code generation, even at runtime for other languages too. In the worst case you can always generate a string and call eval() on it. However it makes a big difference whether code generation is an integral part of the language or an error-prone kludge like this.Also, while Lisp certainly doesn't have the popularity of C, C# or Javascript these days, it is still widely used, both the native Common Lisp implementations and things like Clojure (which runs on top of Java's JVM and interoperates with Java). Just look at the number of job ads looking for Common Lisp/Clojure/AutoLisp programmers.And when it comes to functional languages as such - Erlang & Elixir are big in telecom industry, Haskell in finance where performance and correctness are kings (it is said that if you get a Haskell program to compile, it is almost certainly going to work correctly due to the extremely strong type system of the language), Scala is widely used in the Java ecosystem, etc.These are very far from "almost exclusively teaching languages". In fact, the opposite is true - any of the above would be pretty unsuitable as a teaching (not research!) language because they are way too complex for that. You certainly won't find an university using Common Lisp as a Programming 101 language. In fact, this complexity is exactly why Scheme/Racket were originally created - Common Lisp specification is over 1100 pages. Scheme spec is less than 100.

author: djnz
author_rank: Regular Contributor
timestamp: January 30, 2020, 08:03:38 am
content: Racket (PLT Scheme and the Dr.Scheme environment) was what was used at MIT till the last decade to teach the introductory CS class based on SICP book:https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book.html

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 30, 2020, 03:46:43 pm
content: Yes, let's not forget that Lisp and later Scheme are both MIT work and not surprinsingly they were (Scheme still I think?) used there to teach programming.AFAIK, Racket itself is from Rice university initially, and of course is a strong descendent of the two above.Yes all those are initially teaching/academic work.

author: frogg
author_rank: Regular Contributor
timestamp: January 30, 2020, 04:05:22 pm
content: Just a note of clarification: I was referring to those languagesproper.As janoc clearly described, there are many Lisp derivatives in commercial use today (I would argue, not widespread as a whole, however, compared to other languages.)