9 ms·
Swift as a C Language REPL
- pjmlp 7y agoGDB can be used as C language REPL since at least late 90's, and lldb as well. And if their pseudo-REPL features aren't enough, there are a couple of C interpreters to choose from. http://www.softintegration.com/ http://www.softintegration.com/ https://gitlab.com/zsaleeba/picoc https://gitlab.com/zsaleeba/picoc https://root.cern.ch/cling https://root.cern.ch/cling
- mlthoughts2018 7y agoCPython is my personal favorite C language REPL.
- ufo 7y agoWhat would I have to do to use gdb as a C repl? I'm not very familiar with gdb other than using the backtrace to debug segmentation faults.
- pjmlp 7y agoCompile your executable with debug info, and then make use of gdb expressions. https://sourceware.org/gdb/current/onlinedocs/gdb/Expressions.html#Expressions https://sourceware.org/gdb/current/onlinedocs/gdb/Expression... It is not fully featured REPL, don't expect to use it to create stuff on the fly, it is more to query and call existing code. For a proper REPL, check one of the listed interpreters.
- rowanG077 7y agoSo what you are saying that it's not actually a C REPL. It's a GDB expression REPL which is very different. What was the original point of your comment?
- solidsnack9000 7y agoThere is the germ of an idea here, for sure. It is very easy to map C libraries to Swift. Binding LibPQ, for example, requires just a five line "module map" file: https://github.com/solidsnack/CLibPQ/blob/master/module.modulemap https://github.com/solidsnack/CLibPQ/blob/master/module.modu... Once you've mapped in the library, trying it out interactively in Swift is easy and fun because of Swift's high-level features.
- hhas01 7y agoWould not be my first choice. A good REPL allows you to write code quickly and off the top of your head. As article notes, Swift’s C pointer/buffer semantics are absolutely horrendous, liable to melt the top of your head instead. If you understand C it just gets in your way. If you don’t understand C it gets in your way even worse. Working with ObjC classes is cleaner, but even that has bridging issues. Incidentally, the Swift REPL itself has another nasty misfeature: it always outputs the fully introspected debug representation of complex values, rather than calling `description`/`debugDescription` where available. Not really an issue when working with pointers, but for native structs and classes with complex internal state it can print screens and screens of unreadable noise, totally defeating the purpose. Conversely, the GUI-based “Swift Playgrounds” REPL prints line output right but lacks the CLI’s persistency so re-evaluates all lines every time a new line is entered, making it useless for stateful work. TL;DR: Swift’s a hairy mess. [paraphrased jwz aphorism goes here]
- coldtea 7y ago>As article notes, Swift’s C pointer/buffer semantics are absolutely horrendous, liable to melt the top of your head instead They look perfectly fine to me. What did you find troubling? >TL;DR: Swift’s a hairy mess. [paraphrased jwz aphorism goes here] The only mess described thus far is in the REPL/Playgrounds for the language, which are not themselves "Swift".
- hhas01 7y agoThere are ten different pointer types, all with different and not easily memorized APIs.
- coldtea 7y agoWell, it's all in the name, no? And the use is rather obvious, mutable vs not, typed vs not, and buffer types (contiguous memory with count of items) or not. If only C had those how safer it would be!
- 7y ago
- brobot182 7y agoMaybe if you had some super-short typealiases it would work, e.g. ‘typealias UnsafeRawPointer = URP’. Otherwise, you get bogged down with all the casting and other FFI stuff. One alternative besides gdb is cling: https://root.cern.ch/cling https://root.cern.ch/cling
- j_m_b 7y agoSo `let` is being used to define a var that is lexically scoped to... the global environment?! I've noticed you can do this in Javascript as well. As a Lisp programmer, its very jarring and seems like a bad practice. Is there a reason you would do this?
- dlivingston 7y agoIn Swift, IIRC, `let` defines a constant reference to a value within the current scope.
- hhas01 7y agoCorrect. `let` = constant binding, `var` = variable binding, and except for top-level (global) declarations they are always block scoped. BUT, there is a gotcha: this “constantness” only applies to the name-value binding, not to the value itself. Thus you can still mutate the content of a let-bound value when that value is a class or class instance. Which kinda defeats the point of having the let/var distinction in the first place. C’s `const` may have its priorities backwards, but least it does what it says on the tin. (And let’s not mention what a PITA Swift gets when you want to work with the contents of complex nested struct-based collections in a language that doesn’t have native pointers/references. Again, it makes C look good.)
- jakear 7y agoOnly because the current scope was the global one.
- zapzupnz 7y ago> As a Lisp programmer, its very jarring and seems like a bad practice. As a programmer of any language, guessing at what something does, not verifying that the guess was right, and then complaining about it seems like a bad practice.
- mit_cs 7y agoIf you know C well, you don't need a replacement for!
- TeMPOraL 7y agoA C REPL in ECL (Embeddable Common Lisp): https://www.reddit.com/r/lisp/comments/bgwtsh/fun_ecl_hack/ https://www.reddit.com/r/lisp/comments/bgwtsh/fun_ecl_hack/ It can be as simple as: (defun c-repl () (loop (fresh-line) (princ "c99> ") (let* ((form (read-line)) (func (eval `(let ((*compile-verbose* nil)) (compile nil (lambda () (ffi:c-inline nil nil :void ,form))))))) (funcall func)))) > (c-repl) c99> printf("HELLO world!\n"); HELLO world! c99> { for(int i=0; i<4; i++) printf("*"); printf("\n"); } **** (Though that doesn't expose all features of C. More work is required to turn it into complete REPL.) Fun thing is, you can just paste the above defun into your ECL REPL and execute it :).