js_of_ocaml calling a function in ocaml from js - node.js

I have a function that uses a mutable variable that takes strings and returns strings. (its a read eval print loop interpreter)
I tried exporting it as such:
let () =
Js.export_all
(object%js
method js_run_repl = Js.wrap_callback js_run_repl
end)
Heres a snippet of the function im exporting
let js_run_repl str =
match String.(compare str "quit") with
| 0 -> "bye"
| _ -> ...
regardless of my input it always returns bye, calling the function directly in ocaml produced the expected behaviour. Heres the output from node:
> var mod = require('./main.bc');
undefined
> mod.js_run("constant P : Prop");
MlBytes { t: 0, c: 'bye', l: 3 }
>
Its also peculiar why the function is called js_run instead of js_run_repl. the latter is undefined according to node.

let () =
Js.export_all
(object%js
method js_run_repl str =
str
|> Js.to_string
|> js_run_repl
|> Js.string
end)
I had to convert the strings explicitly to ocaml strings and back to js

Related

ToArray and ToString return (unit -> string), not string. What should I do?

Notes
Why a type method that should return a string returns a 'unit -> string' instead and how to solve it? does not answer my question because it refers to incorrect input, while I do not have it.
I'm currently having a problem with the functions "ToString" returning a (unit -> string) type and not a string, and "ToArray" returning (unit -> string[]) and not string[]. Attempting to upcast to string[] or string has no success.
Here is the code:
let readZip filepath = ZipFile.OpenRead filepath
let replaceEnvs str = Environment.ExpandEnvironmentVariables str
let listFiles rawDir =
replaceEnvs rawDir
|> Directory.EnumerateFiles
let readModMetadata filepath =
let archive = readZip filepath
(archive.GetEntry "mcmod.info").ToString // Also becomes (unit -> string) and not string
[<EntryPoint>]
let main args =
let mods = listFiles modsFolder
let modAsArray = mods.ToArray // Becomes (unit -> string[]) and not string[]?
0
Why is this so, and is there a way to get only strings?
So I found it out.
You need to specify that no parameters go into the functions. The parenthesis in ToString() do just that, as they differentiate returning a function from returning a result.
I need more coffee.

Add method to string and modify self in Lua

How can I add a method to the string table and modify self inside it ?
Basically, I'm trying to mimic the behaviour of the io.StringIO.read method in python, which reads n char in the string and returns them, modifying the string by "consuming" it.
I tried this:
function string.read(str, n)
to_return = str:sub(1, n)
str = str:sub(n + 1)
return to_return
end
local foo = "heyfoobarhello"
print(string.read(foo, 3))
print(foo)
Output is:
hey
heyfoobarhello
I expected the second line to be only foobarhello.
How can I achieve this ?
To mimic Python's io.StringIO class, you must make an object that stores both the underlying string and the current position within that string. Reading from an IO stream normally does not modify the underlying data.
local StringIO_mt = {
read = function(self, n)
n = n or #self.buffer - self.position + 1
local result = self.buffer:sub(self.position, self.position + n - 1)
self.position = self.position + n
return result
end,
}
StringIO_mt.__index = StringIO_mt
local function StringIO(buffer)
local o = {buffer = buffer, position = 1}
setmetatable(o, StringIO_mt)
return o
end
local foo = StringIO"heyfoobarhello"
print(foo:read(3))
print(foo:read())
Output:
hey
foobarhello
I don't recommend adding this class or method to Lua's string library, because the object has to be more complex than just a string.
You can add methods to the datatype string independently from the string table.
Short example that shows that the string methods even work if string table gets deleted...
string=nil
return _VERSION:upper():sub(1,3)
-- Returning: LUA
So you can add a method...
-- read.lua
local read = function(self, n1, n2)
return self:sub(n1, n2)
end
getmetatable(_VERSION).__index.read=read
return read
...for all strings.
( Not only _VERSION )
And use it...
do require('read') print(_VERSION:read(1,3):upper()) end
-- Print out: LUA

trying to break apart a string in rust

I have this string
abcdef x y z
or this one
"ab cd ef" x y z
I am trying to parse this in rust to
s1 = "abcdef"
arr = ["x","y","z"]
or
s1 = "ab cd ef"
arr = ["x","y","z"]
I tried the following (str is the starting string)
let chars = str.chars().peekable();
let s1:String = if *chars.peek().expect("value isnt empty") == '\"'{
chars.skip(1).take_while(|c| *c!= '\"').collect()
}else{
chars.take_while(|c| *c!= ' ').collect()
};
let remainder_str = chars.collect::<String>();
let remainder = remainder_str.split_whitespace();
let mut arr: Vec<&OsStr> =
remainder.map(|s| OsStr::new(s)).collect();
Ie create an iterator of the chars and walk it down the string pulling bits out as I go.
Doesnt work becuase the first collect eats 'chars'. I am sure I could do it via walking down the array of chars with an index inspecting each one in turn (aka, brute force) but that doesnt seem like idiomatic rust.
Can anybody suggest a better way.
Your idea taken to compilation:
fn doit(str: String) -> (String, Vec<String>) {
let mut chars = str.chars().peekable();
let s1:String = if *chars.by_ref().peek().expect("value isnt empty") == '\"'{
chars.by_ref().skip(1).take_while(|c| *c!= '\"').collect()
}else{
chars.by_ref().take_while(|c| *c!= ' ').collect()
};
let remainder_str = chars.collect::<String>();
let remainder = remainder_str.split_whitespace();
let arr: Vec<String> =
remainder.map(|s| s.to_string()).collect();
(s1, arr)
}
by_ref is possibly your friend here.
Note, however, that this method is very likely not what you actually want, as it allocates stuff all over the place (all the Strings, etc.).
You could be better off using only string slices that refer to the original string.

Julia: Building symbol expressions

I have a repetitive set of boilerplate code that looks like this:
type Object
ptr::Ptr{Void}
function Object()
ptr = ccall( (:createObject, LIB_SMILE), Ptr{Void}, ())
smart_p = new(ptr)
finalizer(smart_p, obj -> ccall( (:freeObject, LIB_SMILE), Void, (Ptr{Void},), obj.ptr ))
smart_p
end
end
I would like to auto-generate a set of these type definitions:
for str = ("Obj1","Obj2","Obj3")
op_fname = symbol(str)
op_create = ???
op_free = ???
#eval begin
type $op_fname
ptr::Ptr{Void}
function ($fname)()
ptr = ccall( ($op_create, LIB_SMILE), Ptr{Void}, ())
smart_p = new(ptr)
finalizer(smart_p, obj -> ccall( ($op_free, LIB_SMILE), Void, (Ptr{Void},), obj.ptr ))
smart_p
end
end
end
end
I have not figured out how to generate the correct "symbol symbols" for op_create and op_free. As in, I need op_create = :(:createObj) but I cannot replicate this. Is there a way to generate the needed symbol in this context?
Thank you.
Update: the original answer works (see below), but as #mlubin points out, QuoteNode is an internal implementation function. The quot function in Base.Meta is better:
import Base.Meta.quot
str = "Obj1"
quot(symbol("create$str"))
returns :(:createObj1). But I don't think that Meta.quot is documented either.
Original answer:
You're looking for QuoteNode:
str = "Obj1"
QuoteNode(symbol("create$str"))
returns :(:createObj1) But this seems like a clear application for a macro!

Optimization of F# string manipulation

I am just learning F# and have been converting a library of C# extension methods to F#. I am currently working on implementing a function called ConvertFirstLetterToUppercase based on the C# implementation below:
public static string ConvertFirstLetterToUppercase(this string value) {
if (string.IsNullOrEmpty(value)) return value;
if (value.Length == 1) return value.ToUpper();
return value.Substring(0, 1).ToUpper() + value.Substring(1);
}
The F# implementation
[<System.Runtime.CompilerServices.ExtensionAttribute>]
module public StringHelper
open System
open System.Collections.Generic
open System.Linq
let ConvertHelper (x : char[]) =
match x with
| [| |] | null -> ""
| [| head; |] -> Char.ToUpper(head).ToString()
| [| head; _ |] -> Char.ToUpper(head).ToString() + string(x.Skip(1).ToArray())
[<System.Runtime.CompilerServices.ExtensionAttribute>]
let ConvertFirstLetterToUppercase (_this : string) =
match _this with
| "" | null -> _this
| _ -> ConvertHelper (_this.ToCharArray())
Can someone show me a more concise implementation utilizing more natural F# syntax?
open System
type System.String with
member this.ConvertFirstLetterToUpperCase() =
match this with
| null -> null
| "" -> ""
| s -> s.[0..0].ToUpper() + s.[1..]
Usage:
> "juliet".ConvertFirstLetterToUpperCase();;
val it : string = "Juliet"
Something like this?
[<System.Runtime.CompilerServices.ExtensionAttribute>]
module public StringHelper =
[<System.Runtime.CompilerServices.ExtensionAttribute>]
let ConvertFirstLetterToUppercase (t : string) =
match t.ToCharArray() with
| null -> t
| [||] -> t
| x -> x.[0] <- Char.ToUpper(x.[0]); System.String(x)
Try the following
[<System.Runtime.CompilerServices.ExtensionAttribute>]
module StringExtensions =
let ConvertFirstLetterToUpperCase (data:string) =
match Seq.tryFind (fun _ -> true) data with
| None -> data
| Some(c) -> System.Char.ToUpper(c).ToString() + data.Substring(1)
The tryFind function will return the first element for which the lambda returns true. Since it always returns true it will simply return the first element or None. Once you've established there is at least one element you know data is not null and hence can call Substring
There's nothing wrong with using .NET library functions from a .NET language. Maybe a direct translation of your C# extension method is most appropriate, particularly for such a simple function. Although I'd be tempted to use the slicing syntax like Juliet does, just because it's cool.
open System
open System.Runtime.CompilerServices
[<Extension>]
module public StringHelper =
[<Extension>]
let ConvertFirstLetterToUpperCase(this:string) =
if String.IsNullOrEmpty this then this
elif this.Length = 1 then this.ToUpper()
else this.[0..0].ToUpper() + this.[1..]

Resources