Constructors and Destructors in Lua? - constructor

I am new to Lua and learning some of the concept by comparing them with other programming languages like Python and Java. I know Java and python both have constructors and destructors. But I didn't find one that is written in pure Lua. I have seen some examples that uses C/C++ with Lua for the constructors but is there any way to make constructors and destructors just in Lua language?

A constructor is any function that creates an object and returns it. To define a destructor, you need a metatable with a __gc metamethod. The __gc metamethod will be called either when the object is garbage-collected or at the end of the program.
local mt = {
-- Destructor
__gc = function(self)
print('Garbage-collecting ' .. self.name)
end,
}
-- Constructor
local function newObject(name)
local o = {name = name}
setmetatable(o, mt)
return o
end

Related

Advanced Parameterization Manual in Chisel

This is inside the chisel library
object Module {
// returns a new Module of type T, initialized with a Parameters instance if _p !=None.
def apply[T<:Module](c: =>T)(implicit _p: Option[Parameters] = None):T
}
I don't understand the =sign in the parameters. What does it represents?
The = in (implicit _p: Option[Parameters] = None) is assigning a default value of None to the parameter _p. That means that unless the otherwise specified there is no Parameter instance assigned to _p.
Just in case you are asking about the => in (c: =>T), the => is means that the first parameter c is a reference to a function that returns an instance of T, where T is a subclass of Module.
There's a bunch of idiomatic features of Scala being employed here: Function Currying, implicit parameters, Functions as first class citizens of the language. It's worth a taking a bit of time to learn the syntax of these things. Check out Chisel's generator-bootcamp tutorial particularly section 3.2 and 3.3 for some of the ways Chisel takes advantage of Scala's syntax
This example has two = signs. The first corresponds to By-name parameters: https://docs.scala-lang.org/tour/by-name-parameters.html.
The former is important because Modules in Chisel must wrapped in Module(...) when they are constructed. We generally accomplish using call by-name:
class MyModule extends Module {
...
}
// This works!
def func(mod: => MyModule) = {
val instance = Module(mod) // The module is constructed inside Module(...)
}
func(new MyModule)
// This doesn't work!
def func(mod: MyModule) = {
val instance = Module(mod)
}
func(new MyModule) // The module is constructed too early, here!
The second is a Default parameter: https://docs.scala-lang.org/tour/default-parameter-values.html. It's mainly a convenience thing:
def func(x: Int = 3) = { println(x) }
func(5) // prints 5
func() // prints 3

Function variable and an array of functions in Chapel

In the following code, I'm trying to create a "function pointer" and an array of functions by regarding function names as usual variables:
proc myfunc1() { return 100; }
proc myfunc2() { return 200; }
// a function variable?
var myfunc = myfunc1;
writeln( myfunc() );
myfunc = myfunc2;
writeln( myfunc() );
// an array of functions?
var myfuncs: [1..2] myfunc1.type;
writeln( myfuncs.type: string );
myfuncs[ 1 ] = myfunc1;
myfuncs[ 2 ] = myfunc2;
for fun in myfuncs do
writeln( fun() );
which seems to be working as expected (with Chapel v1.16)
100
200
[domain(1,int(64),false)] chpl__fcf_type_void_int64_t
100
200
So I'm wondering whether the above usage of function variables is legitimate? For creating an array of functions, is it usual to define a concrete function with desired signature first and then refer to its type (with .type) as in the above example?
Also, is it no problem to treat such variables as "usual" variables, e.g., pass them to other functions as arguments or include them as a field of class/record? (Please ignore these latter questions if they are too broad...) I would appreciate any advice if there are potential pitfalls (if any).
This code is using first class function support, which is prototype/draft in the Chapel language design. You can read more about the prototype support in the First-class Functions in Chapel technote.
While many uses of first-class functions work in 1.16 and later versions, you can expect that the language design in this area will be revisited. In particular there isn't currently a reasonable answer to the question of whether or not variables can be captured (and right now attempting to do so probably results in a confusing error). I don't know in which future release this will change, though.
Regarding the myfunc1.type part, the section in the technote I referred to called "Specifying the type of a first-class function" presents an alternative strategy. However I don't see any problem with using myfunc1.type in this case.
Lastly, note that the lambda support in the current compiler actually operates by creating a class with a this method. So you can do the same - create a "function object" (to borrow a C++ term) - that has the same effect. A "function object" could be a record or a class. If it's a class, you might use inheritance to be able to create an array of objects that can respond to the same method depending on their dynamic type. This strategy might allow you to work around current issues with first class functions. Even if first-class-function support is completed, the "function object" approach allow you to be more explicit about captured variables. In particular, you might store them as fields in the class and set them in the class initializer. Here is an example creating and using an array of different types of function objects:
class BaseHandler {
// consider these as "pure virtual" functions
proc name():string { halt("base name called"); }
proc this(arg:int) { halt("base greet called"); }
}
class HelloHandler : BaseHandler {
proc name():string { return "hello"; }
proc this(arg:int) { writeln("Hello ", arg); }
}
class CiaoHandler : BaseHandler {
proc name():string { return "ciao"; }
proc this(arg:int) { writeln("Ciao ", arg); }
}
proc test() {
// create an array of handlers
var handlers:[1..0] BaseHandler;
handlers.push_back(new HelloHandler());
handlers.push_back(new CiaoHandler());
for h in handlers {
h(1); // calls 'this' method in instance
}
}
test();
Yes, in your example you are using Chapel's initial support for first-class functions. To your second question, you could alternatively use a function type helper for the declaration of the function array:
var myfuncs: [1..2] func(int);
These first-class function objects can be passed as arguments into functions – this is how Futures.async() works – or stored as fields in a record (Try It Online! example). Chapel's first-class function capabilities also include lambda functions.
To be clear, the "initial" aspect of this support comes with the caveat (from the documentation):
This mechanism should be considered a stopgap technology until we have developed and implemented a more robust story, which is why it's being described in this README rather than the language specification.

How do I output the contents of a Set in Pascal?

I'm working with simple sets in Pascal, and simply want to output the contents of a set. Everytime I run the code i get the following error message: 'project1.lpr(17,13) Error: Can't read or write variables of this type'.
here is my code:
program Project1;
{$mode objfpc}{$H+}
uses
sysutils;
type TFriends = (Anne,Bob,Claire,Derek,Edgar,Francy);
type TFriendGroup = Set of TFriends;
Var set1,set2,set3,set4:TFriendGroup; x:integer;
begin
set1:=[Anne,Bob,Claire];
set2:=[Claire,Derek];
set3:=[Derek,Edgar,Francy];
writeln(set1);
readln;
end.
Is there a special method/function to output sets?
thanks
Free Pascal allows write/writeln() of enums without explicit typinfo calls.
So
{$mode objfpc} // or Delphi, For..in needs Object Pascal dialect iirc.
var Person :TFriends;
for Person in Set1 do
writeln(Person);
works fine.
Using WriteStr this can also be written to strings. (writestr functions like write/writestr but then to an string. Originally implemented for ISO/Mac dialects)
You can't directly display the set as a string because there is no type information emitted for it. To do so, your set must be a published property of a class.
Once published in a class, you can use the unit TypInfo to display the set as a string, using the function SetToString(). TypInfo is the FPC unit which does all the compiler reflection things.
Short working example of what you try to do:
program Project1;
{$mode objfpc}{$H+}
uses
sysutils, typinfo;
type
TFriends = (Anne,Bob,Claire,Derek,Edgar,Francy);
TFriendGroup = Set of TFriends;
TFoo = class
private
fFriends: TFriendGroup;
published
property Friends: TFriendGroup read fFriends write fFriends;
end;
Var
Foo: TFoo;
FriendsAsString: string;
Infs: PTypeInfo;
begin
Foo := TFoo.Create;
Foo.Friends := [Derek, Edgar, Francy];
//
Infs := TypeInfo(Foo.Friends);
FriendsAsString := SetToString(Infs, LongInt(Foo.Friends), true);
//
Foo.Free;
writeln(FriendsAsString);
readln;
end.
This program outputs:
[Derek,Edgar,Francy]
To go further:
official documentation about SetToString
this blog article

In what terminology context do functions fall under?

Now I understand that Defining is to Types as Declaring is to Variables. But which one (Declare or Define) do functions/procedures/methods/subroutines fall under? Or do they have their own terminology?
In C and C++ you can declare a function (a function prototype) like this:
int function(int);
And then you can define it later, say, at the end of the file:
int function(int param) {
printf("This is the param: %d", param);
return 0;
}
So you can say that functions in C and C++ can fit into the terminology of both types and variables. It depends on the language you're using too, but this how I learned it.

Function objects in C++ (C++11)

I am reading about boost::function and I am a bit confused about its use and its relation to other C++ constructs or terms I have found in the documentation, e.g. here.
In the context of C++ (C++11), what is the difference between an instance of boost::function, a function object, a functor, and a lambda expression? When should one use which construct? For example, when should I wrap a function object in a boost::function instead of using the object directly?
Are all the above C++ constructs different ways to implement what in functional languages is called a closure (a function, possibly containing captured variables, that can be passed around as a value and invoked by other functions)?
A function object and a functor are the same thing; an object that implements the function call operator operator(). A lambda expression produces a function object. Objects with the type of some specialization of boost::function/std::function are also function objects.
Lambda are special in that lambda expressions have an anonymous and unique type, and are a convenient way to create a functor inline.
boost::function/std::function is special in that it turns any callable entity into a functor with a type that depends only on the signature of the callable entity. For example, lambda expressions each have a unique type, so it's difficult to pass them around non-generic code. If you create an std::function from a lambda then you can easily pass around the wrapped lambda.
Both boost::function and the standard version std::function are wrappers provided by the li­brary. They're potentially expensive and pretty heavy, and you should only use them if you actually need a collection of heterogeneous, callable entities. As long as you only need one callable entity at a time, you are much better off using auto or templates.
Here's an example:
std::vector<std::function<int(int, int)>> v;
v.push_back(some_free_function); // free function
v.push_back(&Foo::mem_fun, &x, _1, _2); // member function bound to an object
v.push_back([&](int a, int b) -> int { return a + m[b]; }); // closure
int res = 0;
for (auto & f : v) { res += f(1, 2); }
Here's a counter-example:
template <typename F>
int apply(F && f)
{
return std::forward<F>(f)(1, 2);
}
In this case, it would have been entirely gratuitous to declare apply like this:
int apply(std::function<int(int,int)>) // wasteful
The conversion is unnecessary, and the templated version can match the actual (often unknowable) type, for example of the bind expression or the lambda expression.
Function Objects and Functors are often described in terms of a
concept. That means they describe a set of requirements of a type. A
lot of things in respect to Functors changed in C++11 and the new
concept is called Callable. An object o of callable type is an
object where (essentially) the expression o(ARGS) is true. Examples
for Callable are
int f() {return 23;}
struct FO {
int operator()() const {return 23;}
};
Often some requirements on the return type of the Callable are added
too. You use a Callable like this:
template<typename Callable>
int call(Callable c) {
return c();
}
call(&f);
call(FO());
Constructs like above require you to know the exact type at
compile-time. This is not always possible and this is where
std::function comes in.
std::function is such a Callable, but it allows you to erase the
actual type you are calling (e.g. your function accepting a callable
is not a template anymore). Still calling a function requires you to
know its arguments and return type, thus those have to be specified as
template arguments to std::function.
You would use it like this:
int call(std::function<int()> c) {
return c();
}
call(&f);
call(FO());
You need to remember that using std::function can have an impact on
performance and you should only use it, when you are sure you need
it. In almost all other cases a template solves your problem.