I was just curious, looking around, it seems that Javascript does not have a equals() method like Java. Also, neither == or === can be used to check iff the two operators are the same item. So how is it that Clojurescript has a == and a identical? operator?
Also, should I expect identical? to be substantially faster than == in Clojurescript?
Here's a quick result from the Himera ClojureScript REPL:
cljs.user> =
#<function (a, b) {
return cljs.core._equiv.call(null, a, b)
}>
cljs.user> ==
#<function (a, d, e) {
switch(arguments.length) {
case 1:
return!0;
case 2:
return cljs.core._equiv.call(null, a, d);
default:
return b.apply(this, arguments)
}
throw"Invalid arity: " + arguments.length;
}>
cljs.user> identical?
#<function (a, b) {
return a === b
}>
According to Mozilla's JavaScript Reference on Comparison Operators the === operator does compare to see if the two operands are the same object instance, and since identical? in clojurescript maps directly onto === in JavaScript it will therefore do just that.
The fact that identical? maps directly onto a === b would also suggest that it'll be significantly faster than = or == since they both translate to calls to cljs.core._equiv. However, it wouldn't surprise me if a good JavaScript JIT engine reduced all three to very similar machine code for numbers since the -equiv implementation for numbers just maps onto identical?:
(extend-type number
IEquiv
(-equiv [x o] (identical? x o))
It looks like it's just a macro for ===
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L208
Update based on #dnolen's comment
It's also a function, which just calls ===:
https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L43
Related
Could some one please help me using a if clause in jess, I know the simple sintax but I'm trying to use an && operand so I can use two conditions, but nothing I try seems to work.
if((<(?x ?y) && (>=(?z ?s)) then
....
else
....
Jess has a very regular syntax which is quite unlike the Java syntax you're trying to emulate. All "operators" are actually functions, and use the same prefix syntax as function calls. It's always (op arg1 arg2 ...). The parentheses always surround the whole expression, not just the arguments.
So for example, the Java expression a < b is always (< ?a ?b) in Jess. There is no && operator, but rather, there is an and function. So the Java if (a < b && c > d) ... looks like (if (and (< ?a ?b) (> ?c ?s)) then ... in Jess.
in a Spark process I have an RDD[Try[(A, B)]]. I have to transform this RDD using a function f: B => List[C]. What I want to obtain is an RDD[Try[(A, B, C)], in which I have to flatMap the list obtained from the application of function f.
I tryed this:
val tryRdd = // Obtain the RDD[Try[(A, B)]]
val transformedRdd =
tryRdd.map {
pair =>
for {
(a, b) <- pair
c <- f(b)
} yield {
(a, b, c)
}
}
Unfortunately what I am obtaining is an RDD[Try[Nothing]]. Why? Can anyone help me to understand where I am wrong?
I suppose that problem is not really related to RDD. Probabily RDD with List will end with the same result.
The for-comprehension is translated to
pair.flatMap { case (a, b) => f(b).map { case c => (a, b, c) } }
But f(b).map(...) will give you a List[(A, B, C)], not a Try[(A, B, C)] which you want for the argument of pair.flatMap. So the code shouldn't compile at all (unless you have a strange implicit conversion in scope).
But if you are using, say, IntelliJ, it can fail to show the error and show an incorrect type (or the other way around, it can show errors in working code): you need to actually build the project to see the real errors.
Have you tried to formally type your RDD ?
val transformedRdd : RDD[Try[Tuple3]] = ...
Edit :
If this does raise you an error, then the output of the map is wrong.
The pair variable's type is Try.
Since scala doesn't do it for you, you must add some instruction to interact with its content (the tuple (A,B)).
Plus, you don't have to keep the Try type.
I would use a flatMap to keep successes and clean my RDD.
Something like
val transformedRdd = tryRdd.flatMap {value =>
value match {
case Success((a,b)) => ...
}
}
Watch http://www.scala-lang.org/api/2.9.3/scala/util/Try.html for more informations about the Try class.
I am trying to construct a function "number-crop" which takes three arguments x a b. If x is to the left of the closed interval [a, b] on the number line, then return a. If x is to the right of the interval, then return b. Otherwise, just return x. This is what I have:
(define (number-crop x a b)
(if (max x a b) x b)
(if (min x a b) x a))
I am returned with the error, "define: expected only one expression for the function body, but found 1 extra part". I am new to Racket so I am still trying to understand how if statements work within the language.
Scheme/Racket if expressions always have exactly one condition and exactly two branches. Since they are expressions, not statements, this makes them very useful, and they function much like the conditional “ternary” operator in languages in the C family. However, when you have multiple conditions, you likely want something closer to if...else if chains, which is provided via the cond form.
The cond form is just like if, except with the ability to have any number of “clauses” which are each determined by a single condition. Using cond, your number-crop function would look like this:
(define (number-crop x a b)
(cond
[(< x a) a]
[(> x b) b]
[else x]))
(Note that else is special inside of cond—it replaces the condition for the last clause, and it always runs if the other cases fail.)
This would likely work, but if you already have access to min and max, you don’t actually need to branch at all! If you use those two functions together, you can write number-crop with neither if nor cond:
(define (number-crop x a b)
(min (max a x) b))
This works because composing both min and max will effectively clamp the value within the given range, provided that a is always the minimum and b is always the maximum.
In Scheme (Racket), functions are defined to return one thing. In your case it is clear: the result of the operation you describe. However, Scheme is different from most imperative languages in several respects. For example, if you look at your expression inside the define, it contains two expressions, one after the other. This contradicts the "one expression that calculates the function" assumption in Scheme.
Moreover, even if you write it in an imperative language, you'd use nested ifs, that you can of course use here. Something along the lines of:
(define (number-crop x a b)
(if (= x (max x a b))
b
(if (= x (min x a b))
a
x)))
Is there a way in lisp-family (EDIT: lisp-1) languages to differentiate symbol evaluation with regard to its position as as function or as an argument (i.e. override eval of this symbol in regard to when it is evaluated)?
As an example (I don't need this functionality, this is an example), I wanted to implement some sort of infix operation on a set of objects, which can be called by an object itself
(my-obj some-operator arg1 ...)
which will actually apply function some-operator to my-obj and arguments.
But when this object is used anywhere else in code as an argument, like:
(some-function my-obj &args...)
it will evaluate to a value of my-obj.
Thank you.
In Racket it is possible to do a couple things in this spirit:
You can define a struct and give it a prop:procedure. When an instance of the struct is supplied in an application, the procedure will be called.
You can override the default #%app with your own function, to redefine application generally, and including things that aren't structs. For example you can do things like emulate Clojure's (key map) syntax, so that ('symbol dict) is actually (hash-ref dict 'symbol).
Being a lisp-1 basically means that you do not evaluate the first slot of a combination any differently than any other slots. To get such behavior for code you write anyway, you need to transform it to code that does what you want under the rules of a lisp-1. Thus you will need to implement a macro that performs this transformation.
For example if you want infix operators you need to write some macro infix and then perhaps you could write:
(infix (+ - * /) (1 + 2 * 5 - 3) / 4)
and have it evaluate to 2.
I have been playing around with the idea of a default procedure in a OO CLOS-like Scheme. eg. that writing
(obj 5 10)
Would validate obj and apply it with arguments if obj is a procedure or method, but if it isn't it would be the same as the default dispatcher eg.
(default-dispatcher obj 5 10)
In such Scheme one could make vector accessors:
(define-method default-dispatcher
"Default dispatcher for vectors"
([obj %vector] [index %number]) -> (vector-ref obj index)
([obj %vector] [index %number] value) -> (vector-set! obj index value)
(args ...) -> (error "No such method"))
; example usage
(define vec (vector 4 5 6 7))
[vec 1] ; => 5
[vec 1 10]
[vec 1] ; => 10
In Racket this is possible by changing the languages #%app syntax.
In the TXR Lisp dialect, the problem is approached from the other end. Starting with Lisp-2 dialect as a basis, can we robe ourselves with some of the expressivity advantages of a Lisp-1 dialect, like eliminating the (function ...), #' and funcall noise from programs that make extensive use of higher order functions?
The design is centered around a special operator called dwim, which stands for either "Do What I Mean" or "Dispatch, in a Way that is Intelligent and Meaningful".
Invocations of the dwim operator are sugared over using square brackets, which are called "DWIM Brackets"
The dwim operator isn't just a macro over Lisp-2; it actually changes the name lookup rules. When we have
(dwim a b c (d e f) g)
Or equivalently:
[a b c (d e f) g]
all of the argument forms which are symbolic (a, b, c and g) are resolved using a special rule which conflates together the function and variable namespaces. This is built into the heart of the language. The operator has direct access to the environment to make this possible.
The special treatment does not recurse into (d e f), which is an ordinary Lisp-2 form. You have to put the DWIM Brackets on that if you want the semantics.
Also, the dwim operator is properly handled by macro expansion. For instance, given:
(symacrolet ((localfun whatever))
(flet ((localfun () ...)))
[a b c localfun] ;; refers to the flet as a function object!
(a b c localfun))) ;; refers to the symbol macro!
The macro expander knows about dwim and its semantics, and so it considers the possibility that localfun refers to the function and variable namespace. The closest lexical binding in either namespace is the flet and so the symbol macro expansion is suppressed (shadowed).
The dwim semantics is implicitly used in the partial evaluating op macro and its "cousins" derived from it.
Range Extraction task from Rosetta Code:
(defun range-extract (numbers)
`#{(mapcar [iff [callf > length (ret 2)]
(ret `#[#1 0]-#[#1 -1]`)
(ret `#{#1 ","}`)]
(mapcar (op mapcar car)
(split [window-map 1 :reflect
(op list #2 (- #2 #1))
(sort (uniq numbers))]
(op where [chain second (op < 1)])))) ","}`)
Y Combinator:
;; The Y combinator:
(defun y (f)
[(op #1 #1)
(op f (op [##1 ##1]))])
;; The Y-combinator-based factorial:
(defun fac (f)
(do if (zerop #1)
1
(* #1 [f (- #1 1)])))
;; Test:
(format t "~s\n" [[y fac] 4])
Moreover, various useful things are function callable in TXR Lisp. For instance, every sequence (list, vector or character string) is regarded as a function which maps numeric indices to elements. Thus we can do:
(mapcar "abc" #(2 1 0)) -> #(#\c #\b #\a)
The accepted answer describes a Racket mechanism for treating structures as functions. TXR has this in the form of lambda methods. This is demonstrated in the "OOP-Based" solution to the Accumulator Factory task in Rosetta:
(defstruct (accum count) nil
(count 0))
(defmeth accum lambda (self : (delta 1))
(inc self.count delta))
We can instantiate a (new (accum 9)) which will produce the values 10, 11, 12, ... when invoked as a function. An optional delta argument can be supplied for an increment other than 1:
(let ((acc (new (accum 0))))
(list [acc 5] [acc 5] [acc])) -> (5 10 11)
I'm trying to implement this logic in Clojure (just an example):
a = 1 + 5
b = a + 3
c = a + 4
d = c + a
return f(a, b, c, d)
The best code I've managed to write so far looks like:
(let [a (+ 1 5) b (+ a 3) c (+ a 4) d (+ c a)] (f a b c d))
This looks rather cumbersome, mostly because in my real-life case these "add" operations are much more complicated and may take a few lines of code. I would rather prefer to write it like (Lisp style):
(set a (+ 1 5))
(set b (+ a 3))
(set c (+ a 4))
(set d (+ c a))
(f a b c d)
Is it possible in Clojure?
No and that is by intent, as the (set ...) calls you're describing imply the use of mutable state in the way languages like Java and C# do. This is something Clojure actively avoids in order to manage state in a more sane way, something that really becomes important in concurrency. For more information I refer you to the Clojure website.
Furthermore, the let form is not cumbersome, it is a useful scoping tool:
In your example a, b,c and d are all local to let. What this means is that once the instruction pointer steps out of the let, all of those bindings are forgotten.
In contrast, even if your (set...) example were to work, you would have polluted your namespace with all of these ephemeral names.
Actually, you almost found the best solution possible in Clojure:
(let [a (+ 1 5)
b (+ a 3)
c (+ a 4)
d (+ c a)]
(f a b c d))
You can't write Clojure code in imperative style, because it's a functional language. You can't freely use defs either, because all variables in Clojure are immutable. So, ones defined the can't be changed. So, if you want to temporary bind some variables, you should use let.
The set function in Clojure creates a set data type from another collection container as opposed to mutating the values of the variables. However, you could do the following:
(def a (+ 1 5))
(def b (+ a 3))
(def c (+ a 4))
(def d (+ c a))
(f a b c d)
The let statement allows you to do the same thing but not "pollute" your top-level namespace with the a, b , c, and d values. However, if you want to be able to hang on to and reference a, b, c, and d, a def would do the trick.