initialize an argument of a proc, but not in it's definition line - nim-lang

Suppose that we have an object which has some properties of type proc:
type
x = object
y: proc(a,b:int)
proc myproc(a,b:int) =
echo a
var tmp = new x
tmp.y = myproc # I want to insert initial value in this line for example a = 1
tmp.y(5)
How can I insert initial values in the specified line, and not anywhere else?
Thank you in advance

As far as I know it's not possible to do what you want without other modifications, because you have specified y to be a proc receiving two parameters. So whatever you assign to it, the compiler is always going to expect you to put two parameters at the call site.
One alternate approach would be to use default values in the proc definition:
type
x = object
y: proc(a: int = 1, b: int)
proc myproc(a,b: int) =
echo(a, " something ", b)
var tmp = new x
tmp.y = myproc
tmp.y(b = 5)
The problems with this solution are of course that you can't change the value of a at runtime, and you are forced to manually specify the name of the parameter, otherwise the compiler is going to presume you are meaning the first and forgot to specify b. Such is the life of a non dynamic language.
Another approach is to define the proc as having a single input parameter, and then using an anonymous proc or lambda to curry whatever values you want:
type
x = object
y: proc(a: int)
proc myproc(a,b: int) =
echo(a, " something ", b)
var tmp = new x
tmp.y = proc (x: int) = myproc(1, x)
tmp.y(5)
If you were to use the sugar module, as suggested in the docs, the assignment line could look like:
tmp.y = (x: int) => myproc(1, x)

Related

Can I use where in Haskell to find function parameter given the function output?

This is my program:
modify :: Integer -> Integer
modify a = a + 100
x = x where modify(x) = 101
In ghci, this compiles successfully but when I try to print x the terminal gets stuck. Is it not possible to find input from function output in Haskell?
x = x where modify(x) = 101
is valid syntax but is equivalent to
x = x where f y = 101
where x = x is a recursive definition, which will get stuck in an infinite loop (or generate a <<loop>> exception), and f y = 101 is a definition of a local function, completely unrelated to the modify function defined elsewhere.
If you turn on warnings you should get a message saying "warning: the local definition of modify shadows the outer binding", pointing at the issue.
Further, there is no way to invert a function like you'd like to do. First, the function might not be injective. Second, even if it were such, there is no easy way to invert an arbitrary function. We could try all the possible inputs but that would be extremely inefficient.

The runtime constant in forward declaration

How do we do runtime constant in forward definition/declaration by any way around (tried hard not work on using let)
let n :int
proc m : int =
let i=1
var u=n+i
n=m()
error for this or for other varied ones:
Error: 'let' symbol requires an initialization
Error: redefinition of 'n'; previous
... etc
Please solve it out, thanks before
It's hard to say what you are trying to do with this code, a let variable is treated as a constant, so it can't be modified, but presumably your intent is to use the variable as a sort of counter to increase itself and presumably reassign n multiple times by calling m()? If you remove the n from the proc you can write the code like:
proc m : int =
let i=1
var u=0+i
let n :int = m()
So if you actually want n to be mutable, there's no problem using a var:
var n :int
proc m : int =
let i=1
var u=n+i
u
n=m()
echo n
Note that I had to add u as a last line to the m proc, because otherwise you were returning nothing and the assignment to n would always be zero, which is the default value for the implicit result variable inside a proc that returns something. You can verify this by repeating the n=m() assignment before the last echo.

how to create an IntSet on the heap in nim?

There are various libraries in nim that return actual objects, rather than references. Sometimes I want an object on the heap (regardless of efficiency) -- for instance when I have a generic procedure that expects a ref to an object.
The only way to construct an IntSet on the heap I have found is:
proc newIntSet() : ref IntSet =
new(result)
assign(result[], initIntSet())
This seems to work, but feels like a hack. I worry if it only seems to work. (Are the structures copied by "assign" properly cleaned up?) Is there a better way? Is there a more generic way that will work with other objects?
Your code is perfectly valid. The resulting reference will be subject to garbage collection as any other referefence.
If you find yourself doing this often, you can define the following makeRef template to get rid of the code repetition:
template makeRef(initExp: typed): expr =
var heapValue = new(type(initExp))
heapValue[] = initExp
heapValue
Here is an example usage:
import typetraits
type Foo = object
str: string
proc createFoo(s: string): Foo =
result.str = s
let x = makeRef createFoo("bar")
let y = makeRef Foo(str: "baz")
echo "x: ", x.type.name, " with x.str = ", x.str
Which will output:
x: ref Foo with x.str = bar

Ocaml - empty reference

How to create a empty reference? I mean something lika as
let x = ref Null
or
let x = ref None
or
let x = ref ()
There is no such thing in ML. A value of type t ref always holds a value of type t. This way, the curse of null pointer exceptions is avoided.
If you really need a nullable reference then you have to create a reference of type t option ref:
let r : int option ref = ref None
...
r := Some 5
The type system then ensures that you don't forget to handle the None case, e.g. with a match:
match !r with
| Some n -> ...
| None -> (* What now? *)
You should very rarely need such a thing, though. If you find yourself wanting an option ref then you should first try to restructure the problem.
It's hard to tell what you're asking. There's nothing predefined named Null in OCaml. There is something named None, and indeed you can say let x = ref None. You can also say let x = ref (). However it's hard to imagine a case where you'd want to do this. Since () is the only value of its type, you could never set x to any other value. So there would be no reason to use a reference.
Here is a session showing how to use ref None.
# let x = ref None;;
val x : '_a option ref = {contents = None}
# x := Some 5;;
- : unit = ()
# x;;
- : int option ref = {contents = Some 5}
# x := None;;
- : unit = ()
# x;;
- : int option ref = {contents = None}
Generally speaking an option type like int option allows you to have either an int value (like Some 5) or no value (None). Using a reference like int option ref gives you a mutable value that you can change between these two.
It looks to me like you're trying to reproduce patterns that you use in other languages. If possible you should try to learn OCaml in its own terms.

Haskell: Need Enlightenment with Calculator program

I have an assignment which is to create a calculator program in Haskell. For example, users will be able to use the calculator by command lines like:
>var cola =5; //define a random variable
>cola*2+1;
(print 11)
>var pepsi = 10
>coca > pepsi;
(print false)
>def coke(x,y) = x+y; //define a random function
>coke(cola,pepsi);
(print 15)
//and actually it's more complicated than above
I have no clue how to program this in Haskell. All I can think of right now is to read the command line as a String, parse it into an array of tokens. Maybe go through the array, detect keywords such "var", "def" then call functions var, def which store variables/functions in a List or something like that. But then how do I store data so that I can use them later in my computation?
Also am I on the right track because I am actually very confused what to do next? :(
*In addition, I am not allowed to use Parsec!*
It looks like you have two distinct kinds of input: declarations (creating new variables and functions) and expressions (calculating things).
You should first define some data structures so you can work out what sort of things you are going to be dealing with. Something like:
data Command = Define Definition | Calculate Expression | Quit
type Name = String
data Definition = DefVar Name Expression | DefFunc Name [Name] Expression
-- ^ alternatively, implement variables as zero-argument functions
-- and merge these cases
data Expression = Var Name | Add Expression Expression | -- ... other stuff
type Environment = [Definition]
To start off with, just parse (tokenise and then parse the tokens, perhaps) the stuff into a Command, and then decide what to do with it.
Expressions are comparatively easy. You assume you already have all the definitions you need (an Environment) and then just look up any variables or do additions or whatever.
Definitions are a bit trickier. Once you've decided what new definition to make, you need to add it to the environment. How exactly you do this depends on how exactly you iterate through the lines, but you'll need to pass the new environment back from the interpreter to the thing which fetches the next line and runs the interpreter on it. Something like:
main :: IO ()
main = mainLoop emptyEnv
where
emptyEnv = []
mainLoop :: Environment -> IO ()
mainLoop env = do
str <- getLine
case parseCommnad str of
Nothing -> do
putStrLn "parse failed!"
mainLoop env
Just Quit -> do
return ()
Just (Define d) -> do
mainLoop (d : env)
Just (Calculate e) -> do
putStrLn (calc env e)
mainLoop env
-- the real meat:
parseCommand :: String -> Maybe Command
calc :: Environment -> Expression -> String -- or Integer or some other appropriate type
calc will need to look stuff up in the environment you create as you go along, so you'll probably also need a function for finding which Definition corresponds to a given Name (or complaining that there isn't one).
Some other decisions you should make:
What do I do when someone tries to redefine a variable?
What if I used one of those variables in the definition of a function? Do I evaluate a function definition when it is created or when it is used?
These questions may affect the design of the above program, but I'll leave it up to you to work out how.
First, you can learn a lot from this tutorial for haskell programming
You need to write your function in another doc with .hs
And you can load the file from you compiler and use all the function you create
For example
plus :: Int -> Int -- that mean the function just work with a number of type int and return Int
plus x y = x + y -- they receive x and y and do the operation

Resources