Is there a way to capture a name from the environment when using hy.eval? - hy

I'm trying to create functions in hylang and use them from python but the created functions don't seem to have access to the environment passed to hy.eval.
import hy
env = dict(x=5)
func = hy.eval(hy.read_str('(fn [] x)'), env)
print(func())
The call to func results in NameError: name 'x' is not defined. I also tried
hy.eval(hy.read_str('(func)'), env)
without luck (same error). Any ideas?

The first parameter of hy.eval is locals, not globals as for Python's eval. Implicitly using the calling environment works fine, though, so you can write this more straightforwardly as
import hy
x = 5
func = hy.eval(hy.read_str('(fn [] x)'))
print(func())

hy.eval doesn't have a globals parameter but it has a module parameter and by looking at the source I found that module.__dict__ is passed as globals to eval. So the following works:
import hy
from types import ModuleType
env = dict(x=5)
module = ModuleType('<string>')
module.__dict__.update(env)
func = hy.eval(hy.read_str('(fn [] x)'), module=module)
print(func())

Related

Setting file path in imported C function inside Swift Framework

I am trying to use C library source files inside my Cocoa Framework which has function named
void swe_set_ephe_path(char *path);
Which will basically be
swe_set_ephe_path(”C:\\SWEPH\\EPHE”);
for windows.
This library contains other data files which only work after this function is set.
When imported to Swift the function looks like this
swe_set_ephe_path(path: UnsafeMutablePointer<Int8!>)
Since i want to bundle up all the data files in framework and use it in my application, i have done something like this
public class SwissEphemeris {
public init() {
let path = Bundle.main.bundlePath
let swePath = UnsafeMutablePointer<Int8>(mutating: (path as NSString).utf8String)
swe_set_ephe_path(swePath)
}
}
But it seems it's not working and the functions which needs data to be searched in files are not able to operate.
If anybody interested to look into Swiss library documentation, check here for the link,
https://www.astro.com/swisseph/swephprg.htm#_Toc505244836
There are two problems:
First, the resource files are in the “Resources” subdirectory of the framework, not in the top-level framework directory. You can obtain a path to that directory with
let resourcePath = Bundle(identifier: "com.Abhi.SwissFramework")!.resourcePath!
or with
let resourcePath = Bundle(for: type(of: self)).resourcePath!
I suggest to force-unwrap the optionals because you know that the bundle and the resources directory exist. A failure would indicate a build problem which should be detected early.
Second, the C function takes a char * argument even though it does not mutate the passed string. Here you can use the approach from UnsafeMutablePointer<Int8> from String in Swift:
resourcePath.withCString {
swe_set_ephe_path(UnsafeMutablePointer(mutating: $0))
}
Even better: use the dedicated method withUnsafeFileSystemRepresentation() to get the file system representation of the resource path as a C string:
let resourceURL = Bundle(for: type(of: self)).resourceURL!
resourceURL.withUnsafeFileSystemRepresentation {
swe_set_ephe_path(UnsafeMutablePointer(mutating: $0))
}

How to map a 0-argument JavaScript function in PureScript FFI

I am trying to import the following JavaScript function into PureScript using the FFI:
function getGreeting() {
return "Hi, welcome to the show."
}
but I am not sure what the type should be. The closest I get to is something like:
foreign import getGreeting :: Unit -> String
I do want getGreeting to stay a function, and not convert it to a constant.
Is there a better way to write the type? I tried to see what PureScript does if I define a dummy function in PureScript itself with that type of signature:
var getGreeting = function (v) {
return "Hi, welcome to the show.";
};
Is there a way to get rid of that v parameter that is not being used?
TIA
Unit -> String is a perfectly good type for that, or perhaps forall a. a -> String. The latter type may seem too permissive, but we know for sure that the a is unused thanks to parametricity, so that the function still must be constant.
There is really useful packagepurescript-functions which can be helpful in such a situation and if you really have to call this function from Purescript as it is (because I think that it IS really just a constant) you can try:
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Function.Uncurried (Fn0, runFn0)
foreign import getString ∷ Fn0 String
main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
log (runFn0 getString)
I've created this simple javascript module so this example can be tested:
/* global exports */
"use strict";
// module Main
exports.getString = function() {
return "my constant string ;-)";
};

Flink Scala API functions on generic parameters

It's a follow up question on Flink Scala API "not enough arguments".
I'd like to be able to pass Flink's DataSets around and do something with it, but the parameters to the dataset are generic.
Here's the problem I have now:
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.api.scala._
import scala.reflect.ClassTag
object TestFlink {
def main(args: Array[String]) {
val env = ExecutionEnvironment.getExecutionEnvironment
val text = env.fromElements(
"Who's there?",
"I think I hear them. Stand, ho! Who's there?")
val split = text.flatMap { _.toLowerCase.split("\\W+") filter { _.nonEmpty } }
id(split).print()
env.execute()
}
def id[K: ClassTag](ds: DataSet[K]): DataSet[K] = ds.map(r => r)
}
I have this error for ds.map(r => r):
Multiple markers at this line
- not enough arguments for method map: (implicit evidence$256: org.apache.flink.api.common.typeinfo.TypeInformation[K], implicit
evidence$257: scala.reflect.ClassTag[K])org.apache.flink.api.scala.DataSet[K]. Unspecified value parameters evidence$256, evidence$257.
- not enough arguments for method map: (implicit evidence$4: org.apache.flink.api.common.typeinfo.TypeInformation[K], implicit evidence
$5: scala.reflect.ClassTag[K])org.apache.flink.api.scala.DataSet[K]. Unspecified value parameters evidence$4, evidence$5.
- could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[K]
Of course, the id function here is just an example, and I'd like to be able to do something more complex with it.
How it can be solved?
you also need to have TypeInformation as a context bound on the K parameter, so:
def id[K: ClassTag: TypeInformation](ds: DataSet[K]): DataSet[K] = ds.map(r => r)
The reason is, that Flink analyses the types that you use in your program and creates a TypeInformation instance for each type you use. If you want to create generic operations then you need to make sure a TypeInformation of that type is available by adding a context bound. This way, the Scala compiler will make sure an instance is available at the call site of the generic function.

Lua :new from C API

I am working on a scripting layer for my game engine. Currently I am using a Script as a Class, adding a method to the "Table" named new. This function basically created an instantiated copy of the Class. I call this function from the C API when an instance of the script is needed.
function PlayerController:new(o)
print('A new instance of the PlayerController has been created');
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
My question is: How can I take the above Lua code, and move that into C so it is not required to be added to every script file I write for this system?
You might want to create a class declaration function to do this for you. Here is a complete "helper.lua" file:
local lib = {type = 'helper'}
local CALL_TO_NEW = {__call = function(lib, ...) return lib.new(...) end}
function lib.class(class_name, tbl)
local lib = tbl or {}
lib.type = class_name
lib.__index = lib
-- Default "new" method
function lib.new()
return setmetatable({}, lib)
end
-- Enable foo.Bar() instead of foo.Bar.new()
return setmetatable(lib, CALL_TO_NEW)
end
return lib
Usage example:
local helper = require 'helper'
local lib = helper.class 'foo.Bar'
-- optional new function if there needs to be some argument handling
function lib.new(args)
local self = {}
-- ...
return setmetatable(self, lib)
end
return lib
lub.class
This is a real world minimal class declaration and setup system. It is used in many luarocks such as xml, yaml, dub, etc:
documentation
source code

Lua C api : How to load lua files defined as modules?

I have the following lua script :
module("modoo",package.seeall)
foo=1
bar={12,34}
Which works fine using the cli, such as :
> dofile "mod_modoo.lua"
> =modoo.foo
1
> =modoo
table: 0x86ce058
As far as I understood, it works like a table, but whenever I try loading it as a table, a nil value is pushed onto the stack. Every other table works normally.
I thought using lua_getglobal wouldn't work with modules, but I couldn't find the proper way to load it either ; how should I do it ?
Load Lua modules with require like lua.c does. See http://www.lua.org/source/5.1/lua.c.html#dolibrary
Instead of using module and dofile, it is better practice in Lua 5.1 to simply return a table representing your module when the script is run. All functions and variables should be declared as local within the module script so that the returned table provides the only access point and no globals from other modules are trampled. The module should be imported using require as follows.
mod_modoo.lua:
return { foo = 1, bar = { 12, 34 } }
modoo_test.lua:
> local modoo = require "mod_modoo"
However, it is often nice to bring the module table (i.e. modoo) in as a global without explicitly assigning it. To do so, assign the module table a global reference in addition to returning it from the script. In that case, the module can be used as follows:
mod_modoo.lua:
modoo = { foo = 1, bar = { 12, 34 } }
return modoo
modoo_test.lua:
> require "mod_modoo"
> print(modoo.foo)
1
See the Lua Module Function Critiqued article for more information on the matter.

Resources