4 ms·
Actually Common Lisp supports a gazillion of different programming styles. The version with small functions, similar to the Haskell version: (subseq
by lispm 11y ago
Actually Common Lisp supports a gazillion of different programming styles.
The version with small functions, similar to the Haskell version:
(subseq
(remove-if
(complement #'numberp)
(butlast list 3))
0 5)
In above Common Lisp code, we use four different functions which do one task:
* subseq sequence start &optional end => subsequence
* remove-if test sequence => result-sequence
* complement function => complement-function
* butlast list &optional n => result-list
For different approaches see Common Lisp libraries like Series or Iterate... Iterate is LOOP on steroids.
http://series.sourceforge.net http://series.sourceforge.net
https://common-lisp.net/project/iterate/ https://common-lisp.net/project/iterate/
> This is known as composability, or the UNIX philosophy. In Lisp a procedure tends to accept many options which configure its behaviour.
Check out the UNIX man for tail, grep, ... to see how strange above quote about 'unix philosophy' is. In reality Unix commands are programs with obscene amount of configuration options, sometimes piping data as text around, sometimes glued together by strange shell languages...
- jfb 11y ago> Check out the UNIX man for tail, grep, ... to see how strange above quote about 'unix philosophy' is. I wish someone would take that hoary old meme out behind the barn and put it out of our collective misery.
- qwertyuiop924 11y agounix commands may not be the pinnacle of minimalism, but the most important thing UNIX taught is about composability. Yes, I did recognize the irony of the fact that the common lisp example was much more like a unix command line than the haskell example, but if you're talking about composing (relatively) small commands, unix is still a pretty good comparison.
- nightski 11y agoFor being a pinnacle it is really unsatisfying. It tells you very little about how or what programs can be composed. It's either trial and error or reading man pages. In addition every program has to be written to take in anything as there are no constraints. Function composition via types is a much more satisfying take on this problem. It's too bad Unix is regarded as the holy grail of this technique when it barely provides a passable implementation of it. Text just isn't a great medium for IPC.
- nine_k 11y agoUnix commands happily pass around binary streams of any format. The problem is, as you noticed, there is not schema, no uniform (let alone machine-readable) description of accepted / emitted formats. Composability is possible but not entirely trivial, often with a dose of `grep` / `sed` / `cut` between commands. It's also pretty hard to pass a function to a Unix command. Either your command supports its own syntax (grep, find), or you make do writing a loop or a temporary file.
- dllthomas 11y ago"It's also pretty hard to pass a function to a Unix command." On this and a few other points, it would be interesting to allow a process to call out to the shell that it's running below ("... if any" being one of several issues with the idea).
- qwertyuiop924 11y ago... Well, you can pass a string to exec into a command. in fact, unix has its own map like command based on this. It's called xargs.
- dllthomas 11y agoYou can, but that's a different thing - creating a new shell as a child of the command, rather than talking to the parent shell of the command.
- qwertyuiop924 11y agoWhy would you want to do that? I'm kind of curious. I mean, I'm sure you have an application, I just can't think of one. Blub effect, I guess.
- dllthomas 11y agoI've hit a number of small "oh, I could do that if..." use cases over the years; none is really immediately springing to mind. There are things that a shell function can do that a spawned program cannot - mostly to do with affecting shell state. Updating shell variables and opening file descriptors are obvious examples.
- throwaway999888 11y agoI guess that's why Unix-like OSs are so user-friendly. Just like snapping together lego blocks... not really though. It says something about the state of software if Unix is the thing that "taught us about composability". Laughable.
- iheartmemcache 11y agoI can't find anything to support that in the IEEE POSIX ISO spec from the Austin WG, but the GNU toolset definitely supports your assertion. I think it's important to recognize that POSIX is not SCO UNIX (UNIX(tm) is effectively a trademark and nothing more at this point) which is not GNU/Linux which is not LSB(Linux Standard Base). POSIX itself is a huge PCB of bodge-wires due to legacy compliance. On the upside for systemd haters, they can appeal to the 2004 ISO standard as init.d being the "right way". But if you read the rationale behind a bunch of utilities especially in Section B, you'll see why it's so crusty. "This ..worked in SysV so we're going to keep it". The Linux Standard Base specification isn't much better. The whole argument as to 'what is UNIX' is so contrived at this point, but anyone making the argument that GNU coreutils are about composibility are correct (see page 230 of https://www.gnu.org/software/coreutils/manual/coreutils.pdf https://www.gnu.org/software/coreutils/manual/coreutils.pdf). They assert that the Bell Labs UNIX philosophy was effectively "one tool to do one thing well, orthogonal to other tools, to facilitate composibility" (the authors even dedicate an entire proceeding section to demonstrate it) but that's without any direct references to previous specifications. Anyways, I'm with you, and apparently the GNU guys claim the Bell Labs guys were with you as well.
- skissane 11y ago>POSIX is not SCO UNIX (UNIX(tm) is effectively a trademark and nothing more at this point) UNIX is more than just a trademark, more importantly it is the test suite you have to pass to be allowed to use the trademark. And the trademark doesn't belong to SCO, it belongs to The Open Group, a not-for-profit industry consortium (successor to X/Open and the Open Software Foundation.) Does it matter that much? I'm sure it makes it easier to port a package to a certified UNIX, since you know a certain collection of APIs must be there (putting aside the fact that some parts of the UNIX standard are optional)
- qwertyuiop924 11y agoThe bell guys are so much with me that they created plan9, the system I'd rather be running. It's very elegant, but garnered no support, and it's following is INSANE, in that they are incredibly strict in their interpretation of the UNIX way, and think that anything that isn't is awful. I like composability and small systems as much as the next man, but sometimes, you just want LISP.
- kiiski 11y agoThat `butlast` removes the last three elements, but here you were supposed to remove the first three elements. So I guess `cdddr` is what you need. Also, the way the article uses `remove-if-not` is all wrong. The `:start` argument to `remove-if-not` doesn't mean it starts taking elements after the third one, rather it means it starts filtering after it. So (remove-if-not #'evenp '(1 2 3 4 5 6) :start 3) doesn't produce (4 6) as the article assumes. It produces (1 2 3 4 6). And the `:count` argument doesn't mean it returns 5 elements, rather it means it removes 5 elements. So (remove-if-not #'evenp '(1 2 3 4 5 6) :count 1) returns (2 3 4 5 6).
- lispm 11y agoRight, I chose to present just an example. The article wasn't clear what it was talking about.
- sdegutis 11y ago> Check out the UNIX man for tail, grep, ... to see how strange above quote about 'unix philosophy' is. The "UNIX philosophy" is good, it's just that UNIX doesn't really follow it. The C and shell programs that make up UNIX commands are actually UNIX's own little programming language, complete with ad-hoc data types. Look at `cat` for example. It might as well be `str + str...`. Or look at `grep`, it's basically `filter` or `reduce` at heart. But it has to do this per-line, and it has no metadata about the line, it literally just works on string contents. The `head` and `tail` commands aren't much different than `take` and `drop`. Heck there's even a `sort` command. That's why shells that actually use a programming language (e.g. eshell) don't seem so crazy to me. To be honest, I use eshell way more than I use bash, and half the functions I use there are written in lisp rather than bash or C.
- lispm 11y ago> The "UNIX philosophy" is good, it's just that UNIX doesn't really follow it. It never did, beyond some examples in beginner books. > Look at `cat` for example. It might as well be `str + str...`. Or look at `grep`, it's basically `filter` or `reduce` at heart. Then look at the options of `cat`. On my Linux system cat has a -n option, which numbers the output lines. If it were following the 'UNIX philosophy', this option would not exist.
- qwertyuiop924 11y agoUNIX may have been about small commands ("cat -v", anybody?), but its most important property is COMPOSABILITY. You could use small programs to build larger programs, allowing you to do things by gluing together code that you would previously have to write new programs to do. It made this very easy, and you could also do it from within C, so it wasn't an either/or situation. This is something your namesake system could have learned to do. The Right Thing isn't always the right thing.
- pjmlp 11y agoThat was already available in Xerox PARC systems, by making use of function call composition in Interlisp-D REPL, Builders in Smalltalk transcript or live debugger in Mesa/Cedar. The UNIX composition is only a novelty for those that never saw other OSes that surfaced at the same time. After all UNIX just adopted the idea from MULTICS.
- jeffdavis 11y ago"Check out the UNIX man for tail, grep, ... to see how strange above quote about 'unix philosophy' is." I think a lot of that is due to the untyped nature of unix. Everything is text, so you constantly have to specify details about what the actual input is. Not sure if that applies to lisp or not. Granted, that's not the only reason.