How do I do this in Moonscript?
function a:do_something(b)
print(b)
end
Nothing I tried would compile and I didn't see anything in their documentation.
In Lua what you wrote is syntactic sugar for the following:
a.do_something = function(self, b)
print(b)
end
So you would do just that in MoonScript. (note the => as a shorthand for adding self to the front of the function's argument list)
a.do_something = (b) =>
print b
In MoonScript you'd do:
a.dosomething = (self, b) ->
print b
The -> and => symbols are aliases of the function keyword.
a.dosomething = (b) =>
print b
Using the => (Fat arrow) style as above, adds the scope, ie. self, to the arguments list automatically.
what you're looking for is class.__base:
class C
a: (x)=> print x
C.__base.b = (y)=> #a y*2
i=C!
i\b 5
--prints 10
Related
I'm trying to learn Ruby. I want to pass an arbitrary function and an arbitrary list of arguments and keyword arguments into another function.
for example, I have this arbitrary function below
def dummy_func(a, b)
return a+b
end
And I have this wrapper function
def wrapper(func, *args, **kwargs)
func(args, kwargs))
end
I want it so I can pass my arguments in any of the following ways and still return the correct answer
wrapper(dummy_func, a=1, b=2)
wrapper(dummy_func, 1, b=2)
wrapper(dummy_func, a=1, b=2)
wrapper(dummy_func, 1, 2)
Is this possible in Ruby? What would be an idiomatic way of approaching it?
The idiomatic way is to instead yield to a block.
def dummy_func(a, b, key:)
return a+b+key
end
def wrapper
puts yield
end
a = 4
b = 5
c = 6
wrapper do
dummy_func(a ,b, key: c)
end
Since the block is closure it can see all the same variables that the call to wrapper can. Now there's no need to pass wrapper's arguments through.
If you really want to make your wrapper, you can do some introspection to determine what arguments the wrapped function takes.
def dummy_func(a, b=23, key: 42)
return a+b+key
end
def no_keys(a, b=23)
return a+b
end
def wrapper(func, *array, **hash)
method = self.method(func)
takes_array = method.parameters.any? { |p| [:req, :opt, :rest].include?(p[0]) }
takes_hash = method.parameters.any? { |p| [:keyreq, :key, :keyrest].include?(p[0]) }
if takes_array && takes_hash
self.send(func, *array, **hash)
elsif takes_array
self.send(func, *array)
elsif takes_hash
self.send(func, **hash)
else
self.send(func)
end
end
a = 4
b = 5
c = 6
puts wrapper(:dummy_func, a, b, key:c)
puts wrapper(:no_keys, a, b)
But this is quite a bit more complex and less flexible than yielding to a block. This also limits you to "functions" which are really methods on the main object (there are no function references in Ruby). That's why they're called with self.send. Blocks require no assumptions about what is being wrapped.
The closest you can get is keyword arguments:
https://www.justinweiss.com/articles/fun-with-keyword-arguments/
def hello_message(greeting, time_of_day, first_name:, last_name:)
"#{greeting} #{time_of_day}, #{first_name} #{last_name}!"
end
args = ["Morning"]
keyword_args = {last_name: "Weiss"}
hello_message("Good", *args, first_name: "Justin", **keyword_args)
=> "Good Morning, Justin Weiss!"
I'm trying to create a Ruby method that:
1. accepts as input a proc which accepts two arguments and
2. returns as output a proc which takes one argument (the other argument being passed in with the first proc.)
Code below. Everything I've read about how Ruby handles functional scope indicates that I should be able to return a proc.call as a variable, and I don't understand why I'm getting an "unexpected return" error (reproduced below the code)
(I'm obviously a beginning Rubyist...my experience has mostly been in JavaScript, where the mechanics of doing this sort of thing are, I think, much more intuitive.)
--
def partial (proc1, val1)
return Proc.new {|val2| return proc1.call(val1,val2)}
end
adder = Proc.new {|a,b| a + b}
sum_five = partial(adder,5)
sum_five.call(10) # -- expecting 15
# unexpected return
# (repl):13:in `block in partial'
# (repl):20:in `<main>'
In Ruby, procs and lambdas treat return differently.
Procs are designed to work within other Ruby control structures, so in that context a return is from the control structure. Lambdas are much more like stand-alone methods, so return returns from the lambda. You get an error because the proc has no context to return from.
Try this:
def partial (proc1, val1)
return lambda {|val2| return proc1.call(val1,val2)}
end
adder = Proc.new {|a,b| a + b}
sum_five = partial(adder,5)
puts sum_five.call(10) # -- expecting 15
Shorter/cleaner ruby syntax:
def composer(proc1, val1)
-> (val2) { proc1.call(val1, val2) }
end
adder = -> (a,b) { a + b }
sum_five = composer(adder, 5)
sum_five.call(10)
Although I don't understand it's name, Ruby already has a method, Proc#curry, that does this:
adder = Proc.new {|a,b| a + b}
sum_five = adder.curry.call(5)
sum_five.call(10) # => 15
sum_five.call(2) # => 7
just watch out, because curry takes an optional argument, which is the number of arguments it should expect before calling the initial proc, so if you pass it the argument you want as the "default" it'll work weird:
adder = Proc.new {|a,b| a + b}
sum_five = adder.curry(5) # NOTE: This is incorrect
sum_five.call(1) # => returns a Proc
sum_five[1][2][3][4][5] # => 3 (the first 2 arguments got passed, the rest ignored)
Essentially I have a evaluate method that takes something like
['+','2','3']
which would evaluate to 5.
It's currently set up like so,
def evaluate(exp)
f = exp[0]
if f == '+' then
return exp[1].to_i + exp[2].to_i
elsif f == '-' then
return exp[1].to_i - exp[2].to_i
elsif f == '*' then
return exp[1].to_i * exp[2].to_i
elsif f == '/' then
return exp[1].to_i / exp[2].to_i
end
end
This works fine, but there has to be a better way to do this without a giant if. Is there a way for me to convert the symbol and use it? How do typically lisp interpreters handle this?
Ruby's all about dynamic programming. In fact this makes your code ridiculously easy:
def evaluate(exp)
exp[1].to_i.send(exp[0], exp[2].to_i)
end
It'd be even easier if those tokens were converted on the way in:
exp.map! do |token|
case (token)
when /\A\-?\d+\z/
token.to_i
else
token
end
end
Then you get this:
def evaluate(exp)
exp[1].send(exp[0], exp[2])
end
Now this presumes you're only supplying valid operations, that you're not doing anything absurd, but for trivial cases it works quite well.
If you've converted everything and you're looking to make this more extensible:
def evaluate(exp)
op, *args = exp
args.reduce(&op.to_sym)
end
Then you can do this on arbitrary lists:
evaluate([ '+', 2, 1, 3, 4 ])
def evaluate(*args)
operation, *numbers = args
numbers.map!(&:to_i)
numbers.first.public_send(operation, numbers.last)
end
If you expect more, than two numbers to be used:
def evaluate(*args)
operation, *numbers = args
numbers.map!(&:to_i).inject(&operation.to_sym)
end
evaluate('+','2','3', 4, 5, 6)
#=> 20
You can add an initial value if you need to make sure to always return a Numeric from the method (make sure to select any non-zero number, if operation is division or multiplication):
def evaluate(*args)
operation, *numbers = args
initial_value = %w(/ *).include?(operation) ? 1 : 0
numbers.map!(&:to_i).inject(initial_value, &operation.to_sym) #<==== note 0
end
evaluate '+'
#=> 0
from lisp perspective (common lisp to be precise), you can define evaluate as:
(defun evaluate (func &rest args)
(apply func args))
in first line you define evaluate function to take first argument called func, and rest of them (if any) to put in list called args.
then you apply list of arguments stored in args, to function stored in func.
usage examples:
(evaluate #'print "some text, printed by function evaluated by my own code!")
=> "some text, printed by function evaluated by my own code!"
(evaluate #'+ 2 3)
=> 5
this weird looking #' quotes a function name, otherwise "language" would try to evaluate it as it does with all arguments before passing to function.
i also strongly suggest "structure and interpretation of computer programs", at least videos! in the middle there is this great lecture on evaluation, basically heart of (almost) any computer language on 5 whiteboards! (well... green;)
How do typically lisp interpreters handle this?
Lisp uses symbols for global function names. A symbol is a named thing with a few associated informations. One of these can be a function.
CL-USER 42 > (symbol-function '+)
#<Function + 4100044D34>
CL-USER 43 > (funcall (symbol-function '+) 1 2 3 4)
10
So for your simple expression evaluation:
CL-USER 50 > (defun eval-expression (expression)
(destructuring-bind (function &rest arguments)
expression
(apply function arguments)))
EVAL-EXPRESSION
CL-USER 51 > (eval-expression '(+ 1 2 3 4))
10
Symbols itself are organized in packages, which you can imagine as some kind of specialized table. Packages map names to symbols:
CL-USER 52 > (find-symbol "+")
+
:INHERITED
If you would want to evaluate a string, you first have to read the string to convert the string to Lisp data. The reader will look up the symbols, here +, from the current package:
CL-USER 53 > (eval-expression (read-from-string "(+ 1 2 3 4)"))
10
Since you ask how this is typically done.
You create a lookup table from operations to their implementation. And then use the first element to lookup an implementation and pass the remaining elements to that function.
Essentially all you need to implement a lisp is
evaluate
apply
a lookup table
That kernel might even fit into 30–50 lines. I don't think you want us to give you a complete implementation though. That would take all the fun out of writing your own lisp.
I will thus just outline the basic structure…
$table = {
'+' => lambda { |a, b| a + b },
'-' => lambda { |a, b| a - b },
'*' => lambda { |a, b| a * b },
'/' => lambda { |a, b| a.fdiv(b) },
}
def evaluate(args, context = $table)
# A complete implementation of evaluate would make use of apply ...
head, *tail = args
context[head][*tail]
end
def apply
# ...
end
puts evaluate(['/', 4, 3])
# => 1.3333333333333333
It just so happens that your lisp function names and the corresponding Ruby function names are the same. But that will not always be given, using a lookup table is thus a more typical solution. I mapped the lisp / to Ruby's fdiv to demonstrate that.
Fun fact, these first elements are called symbols and actually Ruby uses a very similar mechanism too and hence also has symbols. Internally, Ruby also uses nested lookup tables to organize classes and constants and methods and local variables, et cetera.
A slightly cleaner version of the same:
def evaluate(operation, *numbers)
numbers.map(&:to_i).reduce(operation)
end
evaluate('+', '2', '3') # => 5
evaluate('/', '6', '2', '3') # => 1
There are many different solutions and you can chose one that more pretty for you, there are a few from me:
exp = ['+','2','3']
def evaluate(exp)
exp.map(&:to_i).inject(exp.shift)
end
# > evaluate(exp)
# => 5
def evaluate(operation, *nums)
nums.map(&:to_i).inject(operation)
end
# > evaluate(*exp)
# => 5
The gem binding_of_caller has an example for how to set a variable in a parent scope:
(this just pasted from their readme)
def a
var = 10
b
puts var
end
def b
c
end
def c
binding.of_caller(2).eval('var = :hello')
end
a()
# OUTPUT
# => hello
This is useful, but it's limited by the need to do all variable initialization in a string.
I gave it a little thought and realized that I could use YAML to serialize/deserialize objects.
Take, for example, the following example:
def c
value = YAML.dump [ { a: "b" } ]
binding.of_caller(2).eval("var = YAML.load('#{value}')")
end
a()
# => {a: "b"}
This is cool, but it'd be better if I could avoid serialization altogether and just write a proper do; end; block like so:
# doesnt work
def c
binding.of_caller(2).eval do
# ideally this would set the variable named "var" in the scope of method "a"
var = [ { a: "b" } ]
end
end
How can I accomplish the functionality of this last example? I don't need to use binding_of_caller if there's another way.
This is the best I could do and, I suspect (though I'd truly love to be proven wrong), the best you'll find short of writing your own C extension a la binding_of_caller:
require 'binding_of_caller'
module BindingExtensionEvalBlock
def eval_block(&block)
eval("ObjectSpace._id2ref(%d).call(binding)" % block.object_id)
end
end
class ::Binding
include BindingExtensionEvalBlock
end
The magic is here, of course:
eval("ObjectSpace._id2ref(%d).call(binding)" % block.object_id)
We get the object ID of the Proc and then, in our Binding#eval, use ObjectSpace#_id2ref to retrieve it from wherever it is in memory and call it, passing in the local binding.
Here it is in action:
def a
var = 10
b
puts var
end
def b
c
end
def c
binding.of_caller(2).eval_block do |bnd|
bnd.local_variable_set(:var, [ { a: "b" } ])
end
end
a # => {:a=>"b"}
As you can see, instead of var = [ { a: "b" } ] in our block we must do bnd.local_variable_set(:var, [ { a: "b" } ]). There's no way to change the binding of a block in Ruby, so we have to pass in a binding (bnd) and call Binding#local_variable_set.
I'm trying to understand lambda calculus with procs and ruby. Here is some code:
puts -> x { -> y {x.call(y) } }
# => #<Proc:0x2a3beb0#C:/first-ruby.rb:1 (lambda)>
puts -> x { x + 2}.call(1)
# => 3
What does -> signify in above example? Is the call method passing the value to the caller, so in the first example, value y is passed to y and in the second example, 1 is passed to x? In the second example, why is 1 evaluated to x?
This is a shortcut for the pure lambda expression:
lmbd = -> arg{ something to do with arg } # With ->{} notation
lmbd = lambda { |arg| something to do with arg } # Standard notation
In your first example you invoke puts method with Proc(lambda) object, and that's why you see #<Proc:0x2a3beb0#C:/first-ruby.rb:1 (lambda)> in the output.
In the second example you invoke puts with lmbd.call(1) method, i.e. puts outputs the result of lambda calculation.
So, if you have lmbd variable which is lambda object, you can pass it like any argument and then get it's result by invoke lmbd.call():
lmbd = -> greeting{ puts "#{greeting}, lambda-expression!" }
def say_hello l, text
l.call(text)
end
say_hello lmbd, "Aloha" # => Aloha, lambda-expression!
What does -> signify in above example?
-> is part of the literal syntax for lambdas, just like, say, ' is part of the literal syntax for strings.
Is the .call method just passing the value from to caller,
The call method is the method, which, well, calls (or executes) the lambda. The arguments to the call method are bound to the parameters of the lambda.
so in first example value y is passed to y and in second example 1 is passed to x.
No, in the first example, y is passed to the outer lambda and bound to its x parameter. In the second example, 1 is passed to the lambda and bound to its x parameter.
In second example why how is 1 evaluated to x?
1 does not evalute to x. 1 is an immediate value, and in Ruby, immediate values always evaluate to themselves. 1 will always evaluate to 1, never to x or anything else.
Let's define a function using Ruby lambda.
def plus_two # no args here
->(x) {x + 2} # args go here
end
# assign a value
x = 1
# call it
plus_two.call(x)
# => 3
Your first example is a bit more complex but using this idea you should be able to come up with functional methods.
I'm studying Scala and functional programming is based upon these substitution principles.
Try doing some recursion using these.
It's like calling functions of functions n times.
What would be the base case then?
As for the Lambda Calculus https://github.com/mackorone/lambda/blob/master/intro.pdf
Try to keep things simple and show the steps rather than trying to figure out what a one liner is doing. Yes they are nice but if you can't read it you can't understand it.
Here's something I was just recently working on:
require 'date'
num = DateTime.now.to_time.utc.to_datetime.ajd - 2451545.0
#t = num / 36525.0
# the terms in reverse order form for the array
#l0_a = [1.0/-19880000.0,
1.0/-152990.0,
1.0/499310.0,
0.0003032028,
36000.76982779,
280.4664567]
# make an enumerator
#l0_e = #l0_a.each
# make a lambda to pass the enumerator to.
def my_lambda
->(x) {x.reduce {|acc, el| acc * #t + el} % 360}
end
puts my_lambda.call(#l0_e)
This is mean longitude of the sun formula using enumerator methods and of course a lambda.