I think the issue with syntax like this is that unless the compiler/language is smart enough, this syntax can be significantly slower than traditional for-loops. For-loop blocks are often scoped differently than arbitrary closures, can capture variables differently, and have different performance overheads. Prime example is JS's Array.map being much slower than a native for-loop without optimization.
Depending on how flexible should it be, it can just very well be a temporary class storing the from and to value and returning it and the final ‘do’ having a completely normal for loop inside iterating from from to to. This seems to have at most a (in Java very cheap) single plus allocation (static lambdas compile to static methods so not even that allocates in itself).
So I don’t see why would this base case have any significant overhead. Of course a complete stream api will have some.
The "federated" reboot of C2 has been mostly a failure. Decentralization was a solution looking for a problem. I hope Ward reverts it back to normal. The real problem was bouncer management (riff-raff policing), something replication and decentralization can't fix because it just replicated riff-riff. Some unfortunate person or thing still had to clean it up by studying and tweezering content.
Which is especially frustrating seeing as how the site was once upon a time about as simple as it gets - which naturally meant that it had to be redesigned to be needlessly more complex, because reasons.
;;; -*- LISP -*-
;;; IOTA: Macros for doing I/O correctly.
;;; Bugs/suggestions/complaints to KMP@MC
[...]
;;; IOTA
;;;
;;; Mnemonic Basis: A form of Lambda for doing I/O binding.
;;;
;;; This is a LAMBDA binding macro that will open a lisp file object
;;; in such a way that it is automatically closed when the lambda binding
;;; range is exited.
The following is some sample code (complete with documentation) that I found in my notes and thought might be helpful:
;;; Notes about CLI interrupts:
;;;
;;; A CLI interrupt is what happens when another job sends to yours. It is
;;; normally the case that other jobs will send directly to a user's HACTRN.
;;; If, however, Lisp is interrupted by a CLI message, it can elect to handle
;;; handle the interrupt in an arbitrary way.
;;;
;;; To define a handler, two things must be done:
;;; [1] Place the name of the handler function (function of one arg)
;;; in the variable CLI-MESSAGE.
;;; [2] Enable CLI handling with (SSTATUS CLI T)
;;;
;;; The handler should take a single argument which it probably should ignore
;;; since I have no idea what it is likely to be.
;;;
;;; The handler should open the file "CLA:" in (CLA BLOCK) mode and immediately
;;; discard the first 8 characters which will be garbage.
;;;
;;; The remainder of the stream, until a control-C or an eof, will be the text
;;; of the message sent. It may be read with TYI, READ, etc. and handled
;;; however.
(eval-when (eval compile)
(cond ((not (get 'iota 'version))
(load "liblsp;iota"))))
(defun handle-cli-msg (ignore)
(iota ((stream '((cla)) '(cla block)))
(do ((i 0 (1+ i))) ((= i 8)) (tyi stream))
(do ((c (tyi stream -1) (tyi stream -1)))
((or (= c -1) (= c 3)))
(format t "~&~3,'0O ~@:C~%" c c)))) ;print out chars seen
(setq cli-message 'handle-cli-msg)
(sstatus cli t)
; --------
(defun eval-cli-msg (ignore) ;alternate handler
(iota ((stream '((cla)) '(block cla)))
(do ((i 0 (1+ i))) ((= i 8)) (tyi stream))
(do ((f (read stream nil) (read stream nil)))
((null f))
(errset (eval f) nil)))) ;Quietly evaluate forms...
;; Assumes the other lisp will have EVAL-CLI-MSG as value of CLI-MESSAGE
(defun eval-in-other-lisp (uname jname s-expression)
(iota ((stream `((cli) ,uname ,jname) '(out ascii block)))
(print s-expression stream)))
All these languages took a lot from Lisp (especially former) and functional languages (especially latter). So it's like complaining to Newton that's his laws of mechanics are known by almost everyone these days, so Newton did nothing special.
I think the gist of the article wasn't so much hating Lisp, but hating the culture around it which is a lot of "you're doing it wrong" and feeling superior. A similar culture pervaded Smalltalk back at the commercial height of it. It's the attitude that turns people off.
Something of a shame really. The lispers and Smalltalkers were their own worst enemies back in the day.
Sad. That was totally not the attitude of Smalltalkers or Interlispers when I was at PARC nor when I was MIT-AI but certainly that all predated any commercial "success".
I do feel like there's much less snobbery/more inclusiveness these days. Anyone can open up a browser and start typing something executable, and there are so many sites willing to offer help.
My experience with ParcPlace was as a customer in the 1990s, we found it a struggle to get them to listen to our boring concerns about crud and databases packaging images and whatnot.
has increasingly become to sound hollow or misleading, insofar as the properties and abilities described were solely found in "functional" languages of the time rather than being inherent benefits.
> Most functional languages provide a nice, protected environment, somewhat like JavaLanguage.
So Java, which isn't functional, provides a relatively "protected" environment. So what does "protected" mean and what does this have to do with functional languages again?
> FP encourages safe ways of programming
Depends on syntax and features. Only allowing one true way or providing one true api, is equivalent.
> Functional programs tend to be much more terse
The terseness can contain complicated subtlety. Up to the developer to read it carefully. Non-obviousness isn't a good thing and a level of verbose expression seems to be beneficial.
> FP encourages quick prototyping
Nope.
> FP is modular in the dimension of functionality
Not unique.
etc etc etc
The common assertions about having no-side effects are interesting because I was lured by this when I was younger. Sadly, there are always side effects, even if it's just resource usage or output to some device. The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree. Has it made functional languages more popular/valuable or javascript (which has no such mechanism) less?
I get aggressive when someone says “no side effects in functional programming”. There are always side effects but in pure FP they’re tracked and controlled.
> Only allowing one true way or providing one true api, is equivalent.
Only if that one true way is safe. I'd argue that hidden mutable state (which is the essence of non-functional programming) is inherently unsafe - non-threadsafe by default and, even more dangerously, confusing to the reader by default.
> The terseness can contain complicated subtlety.
Maybe it "can", but usually the terseness just comes from removing pointless clutter.
> a level of verbose expression seems to be beneficial.
Citation needed.
> Sadly, there are always side effects, even if it's just resource usage or output to some device.
Right, but you can isolate and control them, separate them from your business logic.
> The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree.
No it isn't - if it were then we'd see non-functional languages that had effective control of side effects, and we don't.
> a level of verbose expression seems to be beneficial.
Quorumlang did studies on this. Brainfuck is a sufficient example.
> Maybe it "can", but usually the terseness just comes from removing pointless clutter.
Abstraction is not clutter. FP adds new abstractions which have variable syntax across languages or even within the same language.
>> The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree.
> No it isn't - if it were then we'd see non-functional languages that had effective control of side effects, and we don't.
This is circular logic. Languages would use FP if they saw the value because FP is worth using.
A program can be written in a conceptually non-fp language, that is composed of functions without side effect. Practically, this has no advantage, so no effort is put into going farther in that direction with the syntax.
> I'd argue that hidden mutable state (which is the essence of non-functional programming) is inherently unsafe - non-threadsafe by default and, even more dangerously, confusing to the reader by default.
I know side effects are a feature that can be managed, but this requires discipline. People try FP-centric languages, but unless someone pays them, generally people stay away from it except in spurts (eg map, fluent chaining, etc). This should give some pause, as to what that means. GL with whatever.
How so? It's both very verbose and not very maintainable.
> Abstraction is not clutter.
Most of the overhead in non-functional languages is not abstraction.
> FP adds new abstractions which have variable syntax across languages or even within the same language.
What are you talking about? Generally FP languages have less special-case syntax and less special-case concepts, e.g. fewer control flow keywords, exceptions are less prominent, coroutines don't use special keywords or new concepts, mutable variables aren't needed.... I guess do notation is more common in functional languages, but it's a very lightweight piece of syntax sugar that obviates a bunch of what would be special-case syntax in less functional languages: http://philipnilsson.github.io/Badness10k/escaping-hell-with... .
> A program can be written in a conceptually non-fp language, that is composed of functions without side effect.
Static doesn't mean side-effect free, and a binary distinction between "side effect" and "not side effect", while somewhat useful, is very crude. But the biggest issue is that it's not practical to write without side effects unless the language's standard library, ecosystem, and most of all culture support it.
> People try FP-centric languages, but unless someone pays them, generally people stay away from it except in spurts (eg map, fluent chaining, etc). This should give some pause, as to what that means.
On the contrary, popular programming culture creeps slowly in the FP direction every year. Five or ten years ago map was some wacky far-out functional thing.
Having learned FP when what we had available was Lisp, Caml Light and Standard ML with Miranda on the horizon, for me the whole "no side effects" is cargo cult from Haskell curch followers that took over the meaning of FP.
I do find pureness a great feature. While I agree that many things are not unique to FP, or can be easily incorporated into multiparadigm languages, I think having a compiler-enforced “pure” keyword for example would benefit traditional OOP/imperative languages as well. E.g. C would not have to do ugly compiler hacks making common functions like strlen a macro so that the compiler can hoist it out from a for loops conditional for example. Currently they can only assume it through hacks or through inlining.
Of course “pure” functions will have memory/CPU overhead, but that is inevitable. Perhaps you would prefer idempotent and memoizable?
29 comments
[ 4.3 ms ] story [ 51.2 ms ] threadSo I don’t see why would this base case have any significant overhead. Of course a complete stream api will have some.
"This site uses features not available in older browsers."
Ha ha, "iota": great pun!
https://github.com/g000001/MacLISP-compat/blob/master/IOTA.l...
[...] https://www.maclisp.info/pitmanual/system.htmlYou can use any infix op (core or custom) to do a reduction:
[*] 1..10 # 3628800 basically faculty
> not having the insight of Moon (whoever he was)
> …the Lisp guys start talking about the elegance of lambda and cons and PeanoArithmetic
Of all hackers, Dave Moon is about the least likely to want to focus on gratuitous lambdas or Peano arithmetic!
Something of a shame really. The lispers and Smalltalkers were their own worst enemies back in the day.
I do feel like there's much less snobbery/more inclusiveness these days. Anyone can open up a browser and start typing something executable, and there are so many sites willing to offer help.
has increasingly become to sound hollow or misleading, insofar as the properties and abilities described were solely found in "functional" languages of the time rather than being inherent benefits.
> Most functional languages provide a nice, protected environment, somewhat like JavaLanguage.
So Java, which isn't functional, provides a relatively "protected" environment. So what does "protected" mean and what does this have to do with functional languages again?
> FP encourages safe ways of programming
Depends on syntax and features. Only allowing one true way or providing one true api, is equivalent.
> Functional programs tend to be much more terse
The terseness can contain complicated subtlety. Up to the developer to read it carefully. Non-obviousness isn't a good thing and a level of verbose expression seems to be beneficial.
> FP encourages quick prototyping
Nope.
> FP is modular in the dimension of functionality
Not unique.
etc etc etc
The common assertions about having no-side effects are interesting because I was lured by this when I was younger. Sadly, there are always side effects, even if it's just resource usage or output to some device. The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree. Has it made functional languages more popular/valuable or javascript (which has no such mechanism) less?
blah blah blah.
Only if that one true way is safe. I'd argue that hidden mutable state (which is the essence of non-functional programming) is inherently unsafe - non-threadsafe by default and, even more dangerously, confusing to the reader by default.
> The terseness can contain complicated subtlety.
Maybe it "can", but usually the terseness just comes from removing pointless clutter.
> a level of verbose expression seems to be beneficial.
Citation needed.
> Sadly, there are always side effects, even if it's just resource usage or output to some device.
Right, but you can isolate and control them, separate them from your business logic.
> The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree.
No it isn't - if it were then we'd see non-functional languages that had effective control of side effects, and we don't.
Quorumlang did studies on this. Brainfuck is a sufficient example.
> Maybe it "can", but usually the terseness just comes from removing pointless clutter.
Abstraction is not clutter. FP adds new abstractions which have variable syntax across languages or even within the same language.
>> The idea of limiting side effects is simple to achieve through modern language "static" functions and other mechanisms to the same degree. > No it isn't - if it were then we'd see non-functional languages that had effective control of side effects, and we don't.
This is circular logic. Languages would use FP if they saw the value because FP is worth using.
A program can be written in a conceptually non-fp language, that is composed of functions without side effect. Practically, this has no advantage, so no effort is put into going farther in that direction with the syntax.
> I'd argue that hidden mutable state (which is the essence of non-functional programming) is inherently unsafe - non-threadsafe by default and, even more dangerously, confusing to the reader by default.
I know side effects are a feature that can be managed, but this requires discipline. People try FP-centric languages, but unless someone pays them, generally people stay away from it except in spurts (eg map, fluent chaining, etc). This should give some pause, as to what that means. GL with whatever.
How so? It's both very verbose and not very maintainable.
> Abstraction is not clutter.
Most of the overhead in non-functional languages is not abstraction.
> FP adds new abstractions which have variable syntax across languages or even within the same language.
What are you talking about? Generally FP languages have less special-case syntax and less special-case concepts, e.g. fewer control flow keywords, exceptions are less prominent, coroutines don't use special keywords or new concepts, mutable variables aren't needed.... I guess do notation is more common in functional languages, but it's a very lightweight piece of syntax sugar that obviates a bunch of what would be special-case syntax in less functional languages: http://philipnilsson.github.io/Badness10k/escaping-hell-with... .
> A program can be written in a conceptually non-fp language, that is composed of functions without side effect.
Static doesn't mean side-effect free, and a binary distinction between "side effect" and "not side effect", while somewhat useful, is very crude. But the biggest issue is that it's not practical to write without side effects unless the language's standard library, ecosystem, and most of all culture support it.
> People try FP-centric languages, but unless someone pays them, generally people stay away from it except in spurts (eg map, fluent chaining, etc). This should give some pause, as to what that means.
On the contrary, popular programming culture creeps slowly in the FP direction every year. Five or ten years ago map was some wacky far-out functional thing.
Of course “pure” functions will have memory/CPU overhead, but that is inevitable. Perhaps you would prefer idempotent and memoizable?
11 years ago, 44 comments: https://news.ycombinator.com/item?id=1777767