Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Clojure for Lisp Programmers

Name: Anonymous 2011-08-07 8:51

http://blip.tv/clojure/clojure-for-lisp-programmers-part-1-1319721
http://blip.tv/clojure/clojure-for-lisp-programmers-part-2-1319826

It's a great talk. I've seen many people on /prog/ groundlessly criticizing Clojure, and it's sad. It this presentation Rich Hickey addresses all their points and provides a coherent rationale behind Clojure and its various ``unusual" design decisions. Despite being quite lengthy it doesn't get tedious as it quickly jumps from topic to topic, sometimes with interesting questions form the crowd between the jumps. You should definitely watch this video before forming your opinion about Clojure.

Name: Anonymous 2011-08-07 9:01

I did already, this talk made me realize that all toplevel/namespace-level Clojure procedures' bindings are dynamically scoped, that Rich Hickey is aware of it, and that he thinks it is a great feature and a plus. That turned me off more than anything else, even more than the forced lambda-vectors.

Name: Anonymous 2011-08-07 9:06

>>2

can you explain why dynamically scoped namespace-level bindings are wrong?

Name: Anonymous 2011-08-07 9:19

>>2
procedures' bindings are dynamically scoped, that Rich Hickey is aware of it, and that he thinks it is a great feature and a plus

Yes, it provides support for aspect-oriented programming for example. Both Common Lisp and Scheme support dynamic scope to a degree, because it's practical and useful in some situations. Clojure doesn't claim to be a ``pure" functional language, it just promotes it a bit more than the previous Lisps with immutable collections and laziness. Still practical tools are incorporated when it's appropriate.

Name: Anonymous 2011-08-07 9:22

>>2
You mean that instead of Common Lisp's (let ((*random-seed* (get-current-time)))) ...), you have to work around Java's scoping limitions?

Name: Anonymous 2011-08-07 9:26

Then how do you seed use RANDOM in Clojure?

Name: Anonymous 2011-08-07 9:33

>>5,6
You have no idea what you're talking about. Are you the ``In Lisp" guy?

Name: Anonymous 2011-08-07 9:37

>>7
Justify.

Name: Anonymous 2011-08-07 9:41

http://en.wikipedia.org/wiki/Dynamically_scoped#Dynamic_scoping
Wikipedia says that dynamic scoping is exactly what Common Lisp and other classy Lisps do. So >>2 must retarded Schemer and have no authority talking about Clojure, due to his low IQ.

Name: Anonymous 2011-08-07 9:51

>>3
user=> (defn g [x] (first x))
#'user/g
;; This procedure is referentially transparent,
;; it can be optimized to (fn [x] 1).
user=> (defn f [x] (g '(1 2 3 4)))
#'user/f
user=> (f 'my-anus!)  
1
;; It really isn't referentially transparent,
;; because I can rebind `g' and change the meaning
;; of the procedure.
user=> (binding [g rest] (f 'my-anus!))
(2 3 4)
;; If the compiler erroneously did constant-folding,
;; it would have returned 1.
;; The core bindings are not safe either:
user=> (remove even? [1 2 3 4])
(1 3)
user=> (binding [filter (fn [& _] "no")] (remove even? [1 2 3 4])) ;; remove uses filter
"no"


This complicates inlining, constant folding, and other optimizations (see http://dis.4chan.org/read/prog/1309963234/7)
Other than breaking referential transparency, you can't be sure that your code will do what you mean: since it works outside your namespace, someone may rebind a procedure used inside your procedure, without even knowing it will break your code.
So, when using binding on (what probably are) procedure bindings, you either must know all the bindings used by that procedure, and the bindings used by the default (hoping that someone didn't rebound them already) procedure values used in that procedure, all the way up to the core, or hope that everything will be ok.

Clojure's quasiquote is an hack to preserve hygiene in the most retarded way:
user=> 'first
first
user=> `first
clojure.core/first

Clojure needs this hack, and namespaces, because it's not a Lisp-2 like CL, or else their macros would be utterly broken and unusable.
So, this works:
user=> (defmacro m1 [x] `(first ~x))
#'user/m1
user=> (m1 [1])
1
user=> (let [first rest] (m1 [1]))
1

This doesn't:
user=> (defmacro m2 [x] (list 'first x))
#'user/m2
user=> (m2 [1])
1
user=> (let [first rest] (m2 [1]))
()

This is a good enough solution, worse is better, why would you ever want software that works in the 100% of cases, etc.
But macros are not the point here, because both break using the magical binding:
user=> (binding [first rest] (m1 [1]))
()
user=> (binding [first rest] (m2 [1]))
()


So, dynamically scoped procedures:
- Make basic optimizations like inlining, reference inlining, constant folding, and more difficult.
- Make more advanced optimizations that rely on the value of a binding to not change hard/impossible.
- Break referential transparency.
- Break macros.
- Break procedures.
- Break lexical scope (duh).

Name: Anonymous 2011-08-07 9:55

>>9
No:
This is SBCL 1.0.49, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>;.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (defun g (x) (car x))

G
* (defun f (_) (declare (ignore _)) (g '(1 2 3 4)))

F
* (f 'my-anus!)

1
* (flet ((g (&rest _) nil)) (f 'my-anus!))

1
*


Not saying that defvar is not broken too, but CLers are smart enough to use *earmuffs*

Name: Anonymous 2011-08-07 10:02

>>11
What?
Here is example from wikipedia
why it returns 1?

* $ sbcl
This is SBCL 1.0.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>;.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (defparameter x 0)

X
* (defun f () x)

F
* (defun g () (let ((x 1)) (f)))

G
* (g)

1
*

Name: Anonymous 2011-08-07 10:03

>>12
Here is example from wikipedia
why it returns 1?

speak the english properly please

Name: Anonymous 2011-08-07 10:05

>>12
defvar and defparameter declare a new special (dynamically scoped) binding, defun doesn't.
defvar/parametered variables have problems (let is both let and binding), that's why CLers use *earmuffs*. It's not a problem if you use *earmuffs*.

Name: Anonymous 2011-08-07 10:07

>>10
Other than breaking referential transparency, you can't be sure that your code will do what you mean: since it works outside your namespace, someone may rebind a procedure used inside your procedure, without even knowing it will break your code.
Do you know about packages? Do you know that because of this purity-crap Schemes's SYNTAX-CASE is as complex as rocket science and Scheme is a failed and dead language?

Common Lisp: defmacro
---------------
Scheme/Racket: defmacro begin-for-syntax syntax-e syntax->datum syntax->list syntax-property #' (void) quote-syntax datum->syntax syntax-parameter-value syntax-rule raise-syntax-error internal-definition-context? syntax-parameterize make-set!-transformer prop:set!-transformer free-identifier=? syntax-local-value/immediate syntax-local-transforming-module-provides? syntax-local-module-defined-identifiers syntax-local-module-required-identifiers make-require-transformer (require (lib "stxparam.ss" "mzlib")) syntax? (require mzlib/defmacro) define-macro syntax-local-lift-expression (require racket/stxparam-exptime) make-rename-transformer syntax-local-require-certifier make-parameter-rename-transformer syntax-local-value define-syntax-parameter make-provide-transformer syntax-local-provide-certifier syntax-source local-expand/capture-lifts local-transformer-expand/capture-lifts syntax-local-lift-values-expression syntax-local-lift-module-end-declaration syntax-local-lift-require syntax-local-lift-provide syntax-local-name syntax-local-context syntax-local-phase-level syntax-local-module-exports syntax-local-get-shadower syntax-local-certifier syntax-transforming? syntax-local-introduce make-syntax-introducer exn:fail:syntax make-syntax-delta-introducer syntax-local-make-delta-introducer syntax-case define-syntax syntax-rules with-syntax syntax-position syntax-line syntax-column ...

Name: Anonymous 2011-08-07 10:08

>>10
breaking referential transparency
Again you with this bullshit. It doesn't "break" it because no one claimed Clojure is referential transparent to begin with. set! breaks referential transparency, so CL, Scheme aren't referential transparent because of this. No Lisp is. Only strict functional languages like Haskell are. Clojure is not Haskell, it's just closer to it than Scheme or Common Lisp.

Name: Anonymous 2011-08-07 10:08

>>15
It works outside the namespace/package, your point is invalid, uneducated ``in Lisp'' idiot.

Name: Anonymous 2011-08-07 10:08

>>14
It's not a problem if you use *earmuffs*.
What if, instead, one uses custom LET form to rebind global vars?

Name: Anonymous 2011-08-07 10:10

>>17
Can it be fixed to work with packages, like CL does?

Name: Anonymous 2011-08-07 10:12

>>17
I will pick uneducated idiocy any day, if opposite is dealing with defmacro begin-for-syntax syntax-e syntax->datum syntax->list syntax-property #' (void) quote-syntax datum->syntax syntax-parameter-value syntax-rule raise-syntax-error internal-definition-context? syntax-parameterize make-set!-transformer prop:set!-transformer free-identifier=? syntax-local-value/immediate syntax-local-transforming-module-provides? syntax-local-module-defined-identifiers syntax-local-module-required-identifiers make-require-transformer (require (lib "stxparam.ss" "mzlib")) syntax? (require mzlib/defmacro) define-macro syntax-local-lift-expression (require racket/stxparam-exptime) make-rename-transformer syntax-local-require-certifier make-parameter-rename-transformer syntax-local-value define-syntax-parameter make-provide-transformer syntax-local-provide-certifier syntax-source local-expand/capture-lifts local-transformer-expand/capture-lifts syntax-local-lift-values-expression syntax-local-lift-module-end-declaration syntax-local-lift-require syntax-local-lift-provide syntax-local-name syntax-local-context syntax-local-phase-level syntax-local-module-exports syntax-local-get-shadower syntax-local-certifier syntax-transforming? syntax-local-introduce make-syntax-introducer exn:fail:syntax make-syntax-delta-introducer syntax-local-make-delta-introducer syntax-case define-syntax syntax-rules with-syntax syntax-position syntax-line syntax-column ...

Name: Anonymous 2011-08-07 10:19

>>19
Namespaces are similar to packages, so no.
Remember that Clojure is a Lisp-1.

Name: Anonymous 2011-08-07 10:23

>>20
cretin

Name: Anonymous 2011-08-07 10:24

>>22
Ignore troll posts, thanks.

Name: Anonymous 2011-08-07 10:24

>>21
Packages limit scope, so you're wrong.

>>13
please, define "proper english"

Name: Anonymous 2011-08-07 10:26

>>22>>23
Just admit that I tell truth and you have no arguments.

Name: Anonymous 2011-08-07 10:29

>>24
* (make-package :anus :use '(:cl))
#<PACKAGE "ANUS">
* (in-package :anus)
#<PACKAGE "ANUS">
* (defvar x 1)
X
* (defun f () x)
F
* (export 'x)
T
* (export 'f)
T
* (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">
* (use-package :anus)
T
* (f)
1
* (let ((x 2)) (f))
2

Name: Anonymous 2011-08-07 10:30

>>25
Go back to Israel.

Name: Anonymous 2011-08-07 10:32

>>26
Please, learn how to properly use packages.

Name: Anonymous 2011-08-07 10:33

>>27
I don't see any reason. Perhaps it's you, who should go back there.

Name: Anonymous 2011-08-07 10:41

The main problem with Racket's macro system (and with other syntax-case systems) is that instead of raw s-expressions you're dealing with syntax objects. This becomes very ugly when identifiers are handled: instead of dealing with plain symbols, you're dealing with these syntax values (called “identifiers” in this case) that are essentially a symbol and some opaque information that represents the lexical scope for its source. In several syntax-case systems this is the only difference from defmacro macros, but in the Racket case this applies to everything — identifiers, numbers, other immediate constants, and even function applications, etc — they are all wrapped.

Name: Anonymous 2011-08-07 12:13

Great, the ``in Lisp'' guy is back to troll us with his petty name calling, grade school kid ``define grade school'' rhetoric and general misuse of the English language.

Hadn't we run you away last week? Or was it the week before?

Name: Anonymous 2011-08-07 12:28

>>31
He just keeps coming back, but I'm sure that this one is just an impersonator.

Name: Anonymous 2011-08-07 12:37

>>32
but I'm sure that this one is just an impersonator.
No way, he is genuine. I can clearly see his seal of retardation smeared all over the posts.

Name: Anonymous 2011-08-07 12:43

>>31>>32>>33
Your answer shows that you're out of viable arguments. I will interpret it as your surrender.

Name: Anonymous 2011-08-07 12:44

>>33
Seems you're right: >>34.

Name: Anonymous 2011-08-07 12:45

syntax-rules: syntax-rules

Explicit renaming: er-macro-transformer

Syntactic closures: sc-macro-transformer make-syntactic-closure capture-syntactic-environment

syntax-case: syntax-case syntax datum->syntax syntax->datum identifier? bound-identifier=? free-identifier=?

Common Lisp: symbol-package gensym *gensym-counter* intern unintern

Name: Anonymous 2011-08-07 12:47

ITT Scheme was proven to be an inferior language in comparison to Clojure.

Butthurted fanboys, like >>31, grind their SICPs in blind anger.

Name: Anonymous 2011-08-07 12:51

>>36
syntax-case: syntax-case syntax datum->syntax syntax->datum identifier? bound-identifier=? free-identifier=?
Thank you, but keyword-listing from >>15 is already scary and near the post size limit. Poor Schemers must be mad, rote memorizing all this crud.

Name: Anonymous 2011-08-07 12:52

Let this thread die in peace and ignore the trolls, please.

Name: Anonymous 2011-08-07 13:19

>>39
It's an ok thread, and there is only one troll in it: the ``In Lisp" guy.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List