Ocaml - empty reference - 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.

Related

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

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)

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.

Can I overload the '=' operator for struct-typed arguments?

I want to get a warning everywhere the equals operator '=' is used on struct-typed arguments. It seems that if I define this operator it does not overload, it just redefines '=' to only work for struct-typed arguments, which is not what I want.
[<Obsolete("Possible performance issue with '=' operator on structs. See https://github.com/dotnet/fsharp/issues/526.")>]
let inline (=) (x: ^T) (y: ^T) : bool when ^T: struct and ^T: (static member (=) : ^T * ^T -> bool) =
x = y
let a = obj()
let x = Guid.NewGuid()
let y = Guid.NewGuid()
a = a |> ignore // oh no - "A generic construct requires that the type 'obj' is a CLI or F# struct type."
x = y |> ignore // ok - gets desired warning
Can this be done in F# as is?
Update: found a possible workaround: simply use the [<NoEquality>] attribute on the affected structs; it does mean that all structs need to be annotated but at least it does help.
No, you cannot redefine a globally-scoped (i.e. non-member) function only for some cases. Once a function is in scope, it will always be used, there is no fallback to the previously defined one.

Exposing PureScript types to JavaScript

Can I use PureScript types in JS? For example:
type SomeType = /*type declaration*/
func :: SomeType
func = /*type construction*/
And then in JS do something like this:
let a = module.func()
a instanceof module.SomeType === true
If not if there is any Haskellish language where I can achieve it (Elm, GHCJS, Idris?)?
In general the answer is "no". The runtime representation really depends on what the type is exactly.
For data declarations, every constructor would be represented by a JS "class", like this:
-- PureScript:
data T = A Int | B
x :: T
x = A 42
// JS:
function A(value0) { this.value0 = value0; }
A.create = function(value0) { return new A(value0); }
function B() { }
B.value = new B();
var x = A.create(42);
So you can technically use instanceof to distinguish between cases, but not to determine the type itself.
For a newtype, on the other hand, the type wrapper will be completely erased, because that's the whole point of newtype:
-- PureScript:
newtype T = T Int
x :: T
x = T 42
// JS:
var x = 42;
And for type synonyms (declared with the type keyword), there is no distinct representation. That is, the way such types are represented at runtime is the same as their right-hand side representation:
-- PureScript
type T = Int
x :: T
x = 42
// JS:
var x = 42;
This also applies to naked records, because they are merely type synonyms too:
-- PureScript
type R = { x :: Int, y :: String }
r :: R
r = { x: 42, y: "foo" }
// JS:
var r = { x: 42, y: "foo" }
So the bottom line is: there is no good way to do this. PureScript simply makes no promises about runtime representation. It makes very good promises about program behavior, but not about how it would be implemented in JS (or whatever other backend you happen to be using).
And this is another problem: because PureScript doesn't make any promises like that, it's a very bad idea to rely on your (mine) knowledge of the current implementation, because the next version of the compiler may change it completely. PureScript can do this, because it made no promises. See how that works?
For example, I know there is a pull request in the pipeline somewhere that would switch data representation to arrays, like this:
-- PureScript:
data T = A Int | B
x, y :: T
x = A 42
y = B
// JS:
var x = ["A", 42]
var y = ["B"]
If this pull request is ever accepted, your program will be broken.
In conclusion I can also tell you that neither Elm, nor Haskell, nor Idris will exhibit the property you're after. Runtime type information is generally not a thing valued in the ML universe. One can argue it's effectively present in Idris, in a way, but not in the way you expect.
You may want to try F#/Fable: it's a little bit stronger in this regard, but still not as good as on its native .NET runtime. I don't think you can just check types of F# objects from JS out of the blue, but I know that Fable does support accessing RTTI from F# itself (at extra performance cost), so you can at least make functions to do that and export them to JS.
If you can expand a bit on what your actual problem is, then perhaps I (or someone else) would be able to suggest an alternative solution.

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

Resources