I am a beginner in Racket and I am trying to updare a hash table using hash-update! where the value is a mutable set. Below are the code lines:
(hash-update! hash key (curryr set-add! new_val) (mutable-set 1))
However I receive an error
expected: set?
given: #<void>
argument position: 1st
other arguments...:
x: 2
where I tried 2 as the new_val
Any suggestions ?
This is because the updater is supposed to be a function that takes a value as input and produces a new value output. Since the set is mutable and you're using set-add! to mutate it, the "updater" isn't returning a new value, just mutating the old one and producing void.
There are two ways to fix this:
Mutable sets as values, mutate them separately, not inside hash-update!.
Immutable sets as values, use a functional updater inside hash-update!.
Since you specified you want the values as mutable sets, I will show (1).
The most basic thing you can do is hash-ref to get a mutable-set, and then use set-add! on that.
(set-add! (hash-ref hash key) new-val)
However, this doesn't work when there is no mutable-set value for that key yet. It needs to be added to the table when it doesn't exist yet which why is why you have the (mutable-set 1) failure-result argument. The solution to this isn't hash-update!, it's hash-ref!.
(set-add! (hash-ref! hash key (mutable-set 1)) new-val)
Although it would probably be better if you wrapped the failure-result in a thunk
(set-add! (hash-ref! hash key (λ () (mutable-set 1))) new-val)
Related
In functional programming, we tend to distinguish between data and functions, but what is the difference?
If I consider a constant, I could think of it as a function, which just returns the same value:
(def x 5)
So what is the distinction between data and a function? I fail to see the difference.
Data
Data is a value (with a specific type).
For example, 5 is a value of type Integer, and "abc" is a value of type String. A composite value such as [5 "abc"] has the type Vector.
Two data values of the same type can always be compared for equality.
Data is never executed. That is, the thread of control (aka program counter or PC) never enters the data structure.
Function (aka "code")
A function's only type is "code".
Two functions are never equal, even if they are duplicates of each other.
A function produces a value (with a specific type) when it is executed (possibly with arguments).
Execution means the thread of control enters the code data structure. The code and data values encountered there have complete control over any side-effects that occur, as well as the return value.
Both compiled and interpreted code produce the same results. The only difference between them are implementation details that trade off complexity vs speed.
Eval
The (eval ...) special form accepts data as input and returns a function as output. The returned function can be executed (i.e. invoked) so the thread of control enters the function.
For clarity, the above elides details such as the reader, etc.
Macros are best viewed as a compiler extension embedded within the code, and do not affect the data vs code distinction.
Postscript
It occurred to me that the original question has not been fully answered. Consider the following:
; A Clojure Var pointing to the value 5
(def five 5)
; A Clojure Var pointing to a function that always returns the value 5
(def ->five (fn [& args] 5))
and then use these 2 Vars:
five => 5
(->five) => 5
The parentheses make all the difference.
See also:
Brave Clojure
LispCast
In languages with the property of homoiconicity, code is data and data is code.
This code data duality blurs the distinction between code and data.
(I think your question is about what is the difference between lambda and data - if lambda itself is actually also just a data structure which has to be executed ...)
In homoiconic languages, data can become lambda (if it contains the instructions for a lambda) and vice versa.
So perhaps, the distinction is only by their type (function vs. any other data structure or primitive data type).
Does anyone know the reasons why Julia chose a design of functions where the parameters given as inputs cannot be modified? This requires, if we want to use it anyway, to go through a very artificial process, by representing these data in the form of a ridiculous single element table.
Ada, which had the same kind of limitation, abandoned it in its 2012 redesign to the great satisfaction of its users. A small keyword (like out in Ada) could very well indicate that the possibility of keeping the modifications of a parameter at the output is required.
From my experience in Julia it is useful to understand the difference between a value and a binding.
Values
Each value in Julia has a concrete type and location in memory. Value can be mutable or immutable. In particular when you define your own composite type you can decide if objects of this type should be mutable (mutable struct) or immutable (struct).
Of course Julia has in-built types and some of them are mutable (e.g. arrays) and other are immutable (e.g. numbers, strings). Of course there are design trade-offs between them. From my perspective two major benefits of immutable values are:
if a compiler works with immutable values it can perform many optimizations to speed up code;
a user is can be sure that passing an immutable to a function will not change it and such encapsulation can simplify code analysis.
However, in particular, if you want to wrap an immutable value in a mutable wrapper a standard way to do it is to use Ref like this:
julia> x = Ref(1)
Base.RefValue{Int64}(1)
julia> x[]
1
julia> x[] = 10
10
julia> x
Base.RefValue{Int64}(10)
julia> x[]
10
You can pass such values to a function and modify them inside. Of course Ref introduces a different type so method implementation has to be a bit different.
Variables
A variable is a name bound to a value. In general, except for some special cases like:
rebinding a variable from module A in module B;
redefining some constants, e.g. trying to reassign a function name with a non-function value;
rebinding a variable that has a specified type of allowed values with a value that cannot be converted to this type;
you can rebind a variable to point to any value you wish. Rebinding is performed most of the time using = or some special constructs (like in for, let or catch statements).
Now - getting to the point - function is passed a value not a binding. You can modify a binding of a function parameter (in other words: you can rebind a value that a parameter is pointing to), but this parameter is a fresh variable whose scope lies inside a function.
If, for instance, we wanted a call like:
x = 10
f(x)
change a binding of variable x it is impossible because f does not even know of existence of x. It only gets passed its value. In particular - as I have noted above - adding such a functionality would break the rule that module A cannot rebind variables form module B, as f might be defined in a module different than where x is defined.
What to do
Actually it is easy enough to work without this feature from my experience:
What I typically do is simply return a value from a function that I assign to a variable. In Julia it is very easy because of tuple unpacking syntax like e.g. x,y,z = f(x,y,z), where f can be defined e.g. as f(x,y,z) = 2x,3y,4z;
You can use macros which get expanded before code execution and thus can have an effect modifying a binding of a variable, e.g. macro plusone(x) return esc(:($x = $x+1)) end and now writing y=100; #plusone(y) will change the binding of y;
Finally you can use Ref as discussed above (or any other mutable wrapper - as you have noted in your question).
"Does anyone know the reasons why Julia chose a design of functions where the parameters given as inputs cannot be modified?" asked by Schemer
Your question is wrong because you assume the wrong things.
Parameters are variables
When you pass things to a function, often those things are values and not variables.
for example:
function double(x::Int64)
2 * x
end
Now what happens when you call it using
double(4)
What is the point of the function modifying it's parameter x , it's pointless. Furthermore the function has no idea how it is called.
Furthermore, Julia is built for speed.
A function that modifies its parameter will be hard to optimise because it causes side effects. A side effect is when a procedure/function changes objects/things outside of it's scope.
If a function does not modifies a variable that is part of its calling parameter then you can be safe knowing.
the variable will not have its value changed
the result of the function can be optimised to a constant
not calling the function will not break the program's behaviour
Those above three factors are what makes FUNCTIONAL language fast and NON FUNCTIONAL language slow.
Furthermore when you move into Parallel programming or Multi Threaded programming, you absolutely DO NOT WANT a variable having it's value changed without you (The programmer) knowing about it.
"How would you implement with your proposed macro, the function F(x) which returns a boolean value and modifies c by c:= c + 1. F can be used in the following piece of Ada code : c:= 0; While F(c) Loop ... End Loop;" asked by Schemer
I would write
function F(x)
boolean_result = perform_some_logic()
return (boolean_result,x+1)
end
flag = true
c = 0
(flag,c) = F(c)
while flag
do_stuff()
(flag,c) = F(c)
end
"Unfortunately no, because, and I should have said that, c has to take again the value 0 when F return the value False (c increases as long the Loop lives and return to 0 when it dies). " said Schemer
Then I would write
function F(x)
boolean_result = perform_some_logic()
if boolean_result == true
return (true,x+1)
else
return (false,0)
end
end
flag = true
c = 0
(flag,c) = F(c)
while flag
do_stuff()
(flag,c) = F(c)
end
My program has the following global variable:
let a = (0.0,0.0);;
And the following, where eval e1 returns a string_of_float and somefunc e2 returns a tuple.
let rec output_expr = function
Binop(e1, op, e2) ->
let onDist = float_of_string(eval e1) and onDir = somefunc e2 in
let newA = onDir in (
fprintf oc "\n\t%s" ("blah");
fprintf oc "\n\t%s" ("blah");
fprintf oc "\n\t%s" ("blah");
let a = newA
)
Now, the code above gives me the following error:
Error: This expression has type bool
but an expression was expected of type unit
Command exited with code 2.
I want let a = newA to change the value of the global variable a. How can I do that?
To do it you need to make the value a reference,
let a = ref (0.0, 0.0)
then later that state can change by,
a := (1.0, 2.0);
In a functional world you would not want to have this global state. Sometimes it is very helpful, but in this particular case that is doubtful. You should pass the value a into your function and return a new value (a') that can be used subsequently; note that the value never changes, but new values take the place and are used in further computation.
In your particular case, I think you need to ask yourself why a function named output_expr modifies some global state, or returns anything but unit. But maybe this is a toy example for our consumption, so I will leave it at that.
You cannot assign to a variable (local or global is the same) in OCaml. There's simply no syntax in the language for it. In other words, variables in OCaml are what other languages call "constants" -- they get a value once in initialization, and that's it.
However, you can use a mutable data structure, which offers ways to modify its contents. Data structures are reference types, you can hold a reference to the data structure in a variable, and modify the contents, without needing to assign to the variable.
nlucaroni mentioned such a data structure, ref, which is a simple mutable cell holding a value of the desired type. There are other mutable data structures, like arrays, strings, and any record with mutable fields. Each has its own way of modifying the contents.
However, mutable state can mostly be avoided in functional programming, and if you are relying on mutable state, it may be an indication that you are not doing it the functional way.
In OCaml, values are immutable. You can't change the content of a value and should reorganize your code so that you don't need to.
Here your function output_expr should return the newA and this value should be used instead of a after that.
Actually you can have mutable variables using references but you should only use them if you know what you do and think they are better suited for a particular use case, never because you don't understand immutability.
I would like to know whether or not it's possible to disable return values for specified functions. I am using compiler SBCL. I am asking this, because it takes a while to print the return value, and I don't even need it. Any ideas?
OK, it does the job:
(progn
(...)
t)
Also, thanks for *print-length*.
I find it useful to limit the amount of data printed to my reply by setting the *print-length* variable to a relatively low value in my lisp startup file, like so:
(setf *print-length* 20)
That way, I do not have to worry too much about functions that return a large number of elements.
Using the function values it is possible to return zero (or several) values from a function.
values returns all it's arguments. Thus a function having (values) as it's last form will not return anything, while a function ending with (values val1 val2 val3) will return three values. When calling a function returning several values, only the first one (the primary return value) is available in the normal way, while the other ones may be captured using e.g. multiple-value-bind See the section on Return Values in the Hyperspec for further details
If you want to limit the output from a function that you can not modify, you can call it like this:
(progn
(function-returning-much-data)
(values))
I am using this piece of code and a stackoverflow will be triggered, if I use Extlib's Hashtbl the error does not occur. Any hints to use specialized Hashtbl without stackoverflow?
module ColorIdxHash = Hashtbl.Make(
struct
type t = Img_types.rgb_t
let equal = (==)
let hash = Hashtbl.hash
end
)
(* .. *)
let (ctable: int ColorIdxHash.t) = ColorIdxHash.create 256 in
for x = 0 to width -1 do
for y = 0 to height -1 do
let c = Img.get img x y in
let rgb = Color.rgb_of_color c in
if not (ColorIdxHash.mem ctable rgb) then ColorIdxHash.add ctable rgb (ColorIdxHash.length ctable)
done
done;
(* .. *)
The backtrace points to hashtbl.ml:
Fatal error: exception Stack_overflow Raised at file "hashtbl.ml",
line 54, characters 16-40 Called from file "img/write_bmp.ml", line
150, characters 52-108 ...
Any hints?
Well, you're using physical equality (==) to compare the colors in your hash table. If the colors are structured values (I can't tell from this code), none of them will be physically equal to each other. If all the colors are distinct objects, they will all go into the table, which could really be quite a large number of objects. On the other hand, the hash function is going to be based on the actual color R,G,B values, so there may well be a large number of duplicates. This will mean that your hash buckets will have very long chains. Perhaps some internal function isn't tail recursive, and so is overflowing the stack.
Normally the length of the longest chain will be 2 or 3, so it wouldn't be surprising that this error doesn't come up often.
Looking at my copy of hashtbl.ml (OCaml 3.12.1), I don't see anything non-tail-recursive on line 54. So my guess might be wrong. On line 54 a new internal array is allocated for the hash table. So another idea is just that your hashtable is just getting too big (perhaps due to the unwanted duplicates).
One thing to try is to use structural equality (=) and see if the problem goes away.
One reason you may have non-termination or stack overflows is if your type contains cyclic values. (==) will terminates on cyclic values (while (=) may not), but Hash.hash is probably not cycle-safe. So if you manipulate cyclic values of type Img_types.rgb_t, you have to devise your one cycle-safe hash function -- typically, calling Hash.hash on only one of the non-cyclic subfields/subcomponents of your values.
I've already been bitten by precisely this issue in the past. Not a fun bug to track down.