How do I write a printf() function in AssemblyScript? - printf

I mostly need this for logging where I need to pass in arbitrary arguments (ints floats, objects).
One solution is to write
let i:i32 = 1;
let f:f32 = 1.1;
log ("Message "+i.toString()+" "+f.toString())
This is very awkward and verbose to write.
You can also have multiple log functions, again awkward
log_i (msg:string, i:i32);
log_i2 (msg:string, i:i32, i2:i32);
log_f (msg:string, f:f32);
etc
Seems like you cannot have a generic array that holds i32, f32 and objects at the same time. So not even sure how to pass in varargs. Maybe I can box them but it is again awkward without auto-boxing.
What would be a good solution for this straightforward usecase?

Simply use Typescript style Template strings.
log (`Message ${i} and ${f}.`)
Assemblyscript will automatically generate the toString() and string concatenate statements.
Simple and concise
More expressive logs rather than put all arguments at the end.
No awkward function calls, varargs, etc.

Related

Elm syntax for generating variables and functions: how to tell the difference?

Forgive me if this is a kind of silly question, but I've been going through "Programming Elm" and one thing struck me as a little odd: in the text he shows an example of creating a record,
dog = { name = "Tucker", age = 11 }
and then right after that he shows a function that returns a record
haveBirthday d = { name = d.name, age = d.age + 1 }
To me, the syntax for both seems remarkably similar. How does the compiler know which is which? By the + on the right hand side of the function, that implies change, so it has to be a function? By the fact that there's an argument, d? Or is it that the difference between generating a record and a function is quite obvious, and it's just in this case that they seem so alike? Or is it that in some subtle way that I don't yet have the Zen to grasp, they are in fact the same thing? (That is, something like "everything is a function"?)
I've looked at https://elm-lang.org/docs/syntax#functions -- the docs are very user-friendly, but brief. Are there any other resources that give a more didactic view of the syntax (like this book does for Haskell)?
Thanks for any help along the way.
In an imperative language where "side-effects" are the norm, the term "function" is often used to describe what's more appropriately called a procedure or sub-routine. A set of instruction to be executed when called, and where order of execution and re-evaluation is essential because mutation and other side-effects can change anything from anywhere at any time.
In functional programming, however, the notion of a function is closer to the mathematical sense of the term, where its return value is computed entirely based on its arguments. This is especially true for a "pure" functional language like Elm, which normally does not allow "side-effects". That is, effects that interact with the "outside world" without going through the input arguments or return value. In a pure functional language it does not make sense to have a function that does not take any arguments, because it would always do the same thing, and computing the same value again and again is just wasteful. A function with no arguments is effectively just a value. And a function definition and value binding can therefore be distinguished solely based on whether or not it has any arguments.
But there are also many hybrid programming languages. Most functional languages are hybrids in fact, that allow side-effects but still stick close to the mathematical sense of a function. These languages also typically don't have functions without arguments, but use a special type called unit, or (), which has only one value, also called unit or (), which is used to denote a function that takes no significant input, or which returns nothing significant. Since unit has only one value, it carries no significant information.
Many functional languages don't even have functions that take multiple arguments either. In Elm and many other languages, a function takes exactly one argument. No more and no less, ever. You might have seen Elm code which appears to have multiple arguments, but that's all an illusion. Or syntax sugar as it's called in language theoretic lingo.
When you see a function definition like this:
add a b = a + b
that actual translates to this:
add = \a -> \b -> a + b
A function that takes an argument a, then returns another function which takes an argument b, which does the actual computation and returns the result. This is called currying.
Why do this? Because it makes it very convenient to partially apply functions. You can just leave out the last, or last few, arguments, then instead of an error you get a function back which you can fully apply later to get the result. This enables you to do some really handy things.
Let's look at an example. To fully apple add from above we'd just do:
add 2 3
The compiler actually parses this as (add 2) 3, so we've kind of done partial application already, but then immediately applied to another value. But what if we want to add 2 to a whole bunch of things and don't want write add 2 everywhere, because DRY and such? We write a function:
add2ToThings thing =
add 2 thing
(Ok, maybe a little bit contrived, but stay with me)
Partial application allows us to make this even shorter!
add2ToThings =
add 2
You see how that works? add 2 returns a function, and we just give that a name. There have been numerous books written about this marvellous idea in OOP, but they call it "dependency injection" and it's usually slightly more verbose when implemented with OOP techniques.
Anyway, say we have a list of "thing"s, we can get a new list with 2 added to everything by mapping over it like this:
List.map add2ToThings things
But we can do even better! Since add 2 is actually shorter than the name we gave it, we might as well just use it directly:
List.map (add 2) things
Ok, but then say we want to filter out every value that is exactly 5. We can actually partially apply infix operators too, but we have to surround the operator in parentheses to make it behave like an ordinary function:
List.filter ((/=) 5) (List.map (add 2) things)
This is starting to look a bit convoluted though, and reads backwards since we filter after we map. Fortunately we can use Elm's pipe operator |> to clean it up a bit:
things
|> List.map (add 2)
|> List.filter ((/=) 5)
The pipe operator was "discovered" because of partial application. Without that it couldn't have been implemented as an ordinary operator, but would have to be implemented as a special syntax rule in the parser. It's implementation is (essentially) just:
x |> f = f x
It takes an arbitrary argument on its left side and a function on its right side, then applies the function to the argument. And because of partial application we can conveniently get a function to pass in on the right side.
So in three lines of ordinary idiomatic Elm code we've used partial application four times. Without that, and currying, we'd have to write something like:
List.filter (\thing -> thing /= 5) (List.map (\thing -> add 2 thing) things)
Or we might want to write it with some variable bindings to make it more readable:
let
add2ToThings thing =
add 2 thing
thingsWith2Added =
List.map add2ToThings things
thingsWith2AddedAndWithout5 =
List.filter (\thing -> thing /= 5) thingWith2Added
in
thingsWith2AddedAndWithout5
And so that's why functional programming is awesome.

Should I give up grammatical correctness when naming my functions to offer regularity?

I implement several global functions in our library that look something like this:
void init_time();
void init_random();
void init_shapes();
I would like to add functions to provide a check whether those have been called:
bool is_time_initialized();
bool is_random_initialized();
bool are_shapes_initialized();
However, as you can see are_shapes_initialized falls out of the row due to the fact that shapes is plural and therefore the function name must start with are and not is. This could be a problem, as the library is rather large and not having a uniform way to group similiar functions under the same naming convention might be confusing / upsetting.
E.g. a user using IntelliSense quickly looking up function names to see if the libary offers a way to check if their initialization call happened:
They won't find are_shapes_initialized() here unless scrolling through hundreds of additional function / class names.
Just going with is_shapes_initialized() could offer clarity:
As this displays all functions, now.
But how can using wrong grammar be a good approach? Shouldn't I just assume that the user should also ask IntelliSense for "are_initialized" or just look into the documentation in the first place? Probably not, right? Should I just give up on grammatical correctness?
The way I see it, a variable is a single entity. Maybe that entity is an aggregate of other entities, such as an array or a collection, in which case it would make sense to give it a plural name e.g. a set of Shape objects could be called shapes. Even so, it is still a single object. Looking at it that way, it is grammatically acceptable to refer to it as singular. After all, is_shapes_initialized actually means "Is the variable 'shapes' initialized?"
It's the same reason we say "The Bahamas is" or "The Netherlands is", because we are referring to the singular country, not whatever plural entity it is comprised of. So yes, is_shapes_initialized can be considered grammatically correct.
It's more a matter of personal taste. I would recommend putting "is" before functions that return Boolean. This would look more like:
bool is_time_initialized();
bool is_random_initialized();
bool is_shapes_initialized();
This makes them easier to find and search for, even if they aren't grammatically correct.
You can find functions using "are" to show it is plural in places such as the DuckDuckGo app, with:
areItemsTheSame(...)
areContentsTheSame(...)
In the DuckDuckGo app, it also uses "is" to show functions return boolean, and boolean variables:
val isFullScreen: Boolean = false
isAssignableFrom(...)
In OpenTK, a C# Graphics Library, I also found usage of "are":
AreTexturesResident(...)
AreProgramsResident(...)
In the same OpenTK Libary, they use "is" singularly for functions that return boolean and boolean variables:
IsEnabledGenlock(...)
bool isControl = false;
Either usage could work. Using "are" plurally would make more sense grammatically, and using "if" plurally could make more sense for efficiency or simplifying Boolean functions.
Here's what I would do, assuming you are trying to avoid calling this function on each shape.
void init_each_shape();
bool is_each_shape_initialized();
Also assuming that you need these functions, it seems like it would make more sense to have the functions throw an exception if they do not succeed.

How to make and use an arraylist of functions

How can i make an arraylist of functions, and call each function easily? I have already tried making an ArrayList<Function<Unit>>, but when i tried to do this:
functionList.forEach { it }
and this:
for(i in 0 until functionList.size) functionList[i]
When i tried doing this: it() and this: functionList[i](), but it wouldn't even compile in intellij. How can i do this in kotlin? Also, does the "Unit" in ArrayList<Function<Unit>> mean return value or parameters?
Just like this:
val funs:List<() -> Unit> = listOf({}, { println("fun")})
funs.forEach { it() }
The compiler can successfully infer the type of funs here which is List<() -> Unit>. Note that () -> Unit is a function type in Kotlin which represents a function that does not take any argument and returns Unit.
I think there are two problems with the use of the Function interface here.
The first problem is that it doesn't mean what you might think. As I understand it, it's a very general interface, implemented by all functions, however many parameters they take (or none). So it doesn't have any invoke() method. That's what the compiler is complaining about.
Function has several sub-interfaces, one for each 'arity' (i.e. one for each number of parameters): Function0 for functions that take no parameters, Function1 for functions taking one parameter, and so on. These have the appropriate invoke() methods. So you could probably fix this by replacing Function by Function0.
But that leads me on to the second problem, which is that the Function interfaces aren't supposed to be used this way. I think they're mainly for Java compatibility and/or for internal use by the compiler.
It's usually much better to use the Kotlin syntax for function types: (P1, P2...) -> R. This is much easier to read, and avoids these sorts of problems.
So the real answer is probably to replace Function<Unit> by () -> Unit.
Also, in case it's not clear, Kotlin doesn't have a void type. Instead, it has a type called Unit, which has exactly one value. This might seem strange, but makes better sense in the type system, as it lets the compiler distinguish functions that return without an explicit value, from those which don't return. (The latter might always throw an exception or exit the process. They can be defined to return Nothing -- a type with no values at all.)

Why can Rebol repeat not take a literal word type of value

The Rebol function set accepts an any-word! but repeat only accepts word!
Is there a particular reason that repeat could not also accept a lit-word! ?
repeat uses same syntax as foreach and similar functions. They all accept word! only. I guess there's no particular reason, it's just what people are used to.
lit-word! params can be a bit confusing. That is, when the param is a lit-word!, you're saying "don't evaluate it", so passing a word! means the func is already seeing it as a lit-word!.
R3 only supports word! args in foreach as well, which is more consistent. Things look much cleaner this way, and are the best model when you write your own control funcs and such.

Most appropriate data structure for dynamic languages field access

I'm implementing a dynamic language that will compile to C#, and it's implementing its own reflection API (.NET's is too slow, and the DLR is limited only to more recent and resourceful implementations).
For this, I've implemented a simple .GetField(string f) and .SetField(string f, object val) interface. Until recently, the implementation just switches over all possible field string values and makes the corresponding action.
Also, this dynamic language has the possibility to define anonymous objects. For those anonymous objects, at first, I had implemented a simple hash algorithm.
By now, I am looking for ways to optimize the dynamic parts of the language, and I have come across the fact that a hash algorithm for anonymous objects would be overkill. This is because the objects are usually small. I'd say the objects contain 2 or 3 fields, normally. Very rarely, they would contain more than 15 fields. It would take more time to actually hash the string and perform the lookup than if I would test for equality between them all. (This is not tested, just theoretical).
The first thing I did was to -- at compile-time -- create a red-black tree for each anonymous object declaration and have it laid onto an array so that the object can look for it in a very optimized way.
I am still divided, though, if that's the best way to do this. I could go for a perfect hashing function. Even more radically, I'm thinking about dropping the need for strings and actually work with a struct of 2 longs.
Those two longs will be encoded to support 10 chars (A-za-z0-9_) each, which is mostly a good prediction of the size of the fields. For fields larger than this, a special function (slower) receiving a string will also be provided.
The result will be that strings will be inlined (not references), and their comparisons will be as cheap as a long comparison.
Anyway, it's a little hard to find good information about this kind of optimization, since this is normally thought on a vm-level, not a static language compilation implementation.
Does anyone have any thoughts or tips about the best data structure to handle dynamic calls?
Edit:
For now, I'm really going with the string as long representation and a linear binary tree lookup.
I don't know if this is helpful, but I'll chuck it out in case;
If this is compiling to C#, do you know the complete list of fields at compile time? So as an idea, if your code reads
// dynamic
myObject.foo = "some value";
myObject.bar = 32;
then during the parse, your symbol table can build an int for each field name;
// parsing code
symbols[0] == "foo"
symbols[1] == "bar"
then generate code using arrays or lists;
// generated c#
runtimeObject[0] = "some value"; // assign myobject.foo
runtimeObject[1] = 32; // assign myobject.bar
and build up reflection as a separate array;
runtimeObject.FieldNames[0] == "foo"; // Dictionary<int, string>
runtimeObject.FieldIds["foo"] === 0; // Dictionary<string, int>
As I say, thrown out in the hope it'll be useful. No idea if it will!
Since you are likely to be using the same field and method names repeatedly, something like string interning would work well to quickly generate keys for your hash tables. It would also make string equality comparisons constant-time.
For such a small data set (expected upper bounds of 15) I think almost any hashing will be more expensive then a tree or even a list lookup, but that is really dependent on your hashing algorithm.
If you want to use a dictionary/hash then you'll need to make sure the objects you use for the key return a hash code quickly (perhaps a single constant hash code that's built once). If you can prevent collisions inside of an object (sounds pretty doable) then you'll gain the speed and scalability (well for any realistic object/class size) of a hash table.
Something that comes to mind is Ruby's symbols and message passing. I believe Ruby's symbols act as a constant to just a memory reference. So comparison is constant, they are very lite, and you can use symbols like variables (I'm a little hazy on this and don't have a Ruby interpreter on this machine). Ruby's method "calling" really turns into message passing. Something like: obj.func(arg) turns into obj.send(:func, arg) (":func" is the symbol). I would imagine that symbol makes looking up the message handler (as I'll call it) inside the object pretty efficient since it's hash code most likely doesn't need to be calculated like most objects.
Perhaps something similar could be done in .NET.