Saturday, 23 November 2024

FIC Xixón 2023

While going through the Program of the 2024 FICXixon edition I've realised that I had forgotten to finish and publish my post about the previous edition, indeed, publishing this kind of post 1 year later has become as much a tradition as the fact of writing a post about the festival. OK, here it goes:

One more year and one more FICXixon edition, number 61, from November 17th to November 25th, 2023. Once again I feel that sort of pride when I see how my hometown manages to organize such an excellent event, a middle size city (and a small region) in one corner of our continent, that after striving to survive to different waves of massive economical crisis and population losses, now seems to be on the way to stabilization and even recovery (IT sector, wind turbines factories, small private shipyards, some home workers moving/returning here).

As always I'm a bit constrained by work and by not feeling like going to sessions in those cinemas far away from my flat, (Yelmo in La Calzada, Laboral) and in the end I only attended to 4 sessions (I could not watch Baltimore, by Moldy and Lawlor, as when I finally made up my mind to get a ticket for it it was already sold out). I pretty nailed it with these 4 films, as all of them were good or very good

  • Shoshana. Saturday 18, Teatro Jovellanos. Based on a true story, excellent, absolutely excellent, so much that I should write a separate post for it, but I think that is not happening, so I better write some lines directly here. I've watched quite a bunch of films (normally very good) dealing with the complexities of life in Israel-Palestine, from different angles and perspectives, but I think this is the first one I've watched about the (recent) beginning of all that mess. Set in the 1930's/1940's, in the British colony of Palestine, where European jews have been settling recently, escaping the fascist threat in Europe and pursuing the dream of thriving in the land of their ancestors. Many of them are left-wing, not only the ones in the Kibbutz, also those in Tel-Aviv. They dream of having their own independent state, a homeland, and they buy lands and work hard. Most of them think it will be possible to get along with Arabs, but as the film ends it's sadly clear even for those that believed in "living together" not just in "live separate and not kill each other", that coexisting with Muslims in equality (not in dhimmitude) is for the most part impossible.
  • Day of the Tiger (Tigru). Wednesday 22, OCine. An interesting Romanian film inspired by true events. A woman working in a zoo is going through a bad time and in an error she lets a tiger escape the zoo. A patrol sets off to track the animal and a fucking mother fucker whose main pride and fun in life consists of hunting animals becomes the leader. There was an encounter with the director at the end, where he explained that his love for animals encouraged him to do this film. I was intrigued about where do you find wild animals like these (the tiger role was played by 2 different animals) for a film, if there is a "tiger's casting agency" :-) Well, it's a bit like that. These tigers come from Northern France, where a guy has a huge farm where he takes care of a bunch of wild animals. When the animals are "hired" you also hire the guy, as of course some expert has to handle them during the recording.
  • Disco Boy. Thursday 23, Teatro Jovellanos. Very powerful French drama. A tough story. One Belarusian young man enters illegally in France and decides to join the Foreign Legion, where if he manages to serve for 3 years he will be granted with French citizenship. The way he entered in France is so hard as the way he chose to try to stay. If you know how France works it's revolting. It's revolting that for a guy with a similar culture to ours and that sure would work hard and integrate into the French society without a problem, the Far-Left (anti)French system makes this as hard as possible, while anyone coming from an incompatible culture, with a hatred and distaste for our values, and with a firm desire of profiting from our welfare system, will find all sort of support from all kind of Far-Left associations. I say "ours" in this paragraph cause though I don't have French citizen, I consider it my second home/country/identity/belonging (and I've paid taxes there for years, not like all that scum that is destroying the country).
  • Matronas (Sages-femmes). Saturday 25, OCine. I think I was not particularly expectant about this film, but it was the last day of Festival and I wanted to attend one more screening, and the thing is that it was excellent. I had never thought about how intense and demanding is the work of bringing new lives to this world. This film takes us through the lives of several French women that do just that, working as midwives (sage-femme in Francais). An unattended surprise. When leaving the screening I heard some women that seemed to be midwives themselves praising how they felt reflected on the film.

Friday, 15 November 2024

Python Functions Disallowing Named Arguments

There are some builtin Python functions (written in C) that do not accept named (keyword) arguments (so they force the use of positional ones), for example (range, map, filter...) If you try to pass them a keyword argument you'll get an error: [function] takes no keyword arguments. This feels like an odd limitation to me, and furthermore, very confusing, as when looking into the documentation (for example for functions filter and map) I see no indication of this restriction, so you "learn by trying".

I've been trying to find information about the reason for this odd behaviour, and have not found much. There is this discussion that says that some builtin functions are defined with a "fast header" that does not accept keyword arguments.

This is because they use only a fast simple header ...(... PyObject *args) and therefore all named parameters are rejected automatically. (Python can never introspect into names of arguments in C source. :-)

Many other C functions have a header ...(... PyObject *args, PyObject *kwds) and they support exact list of names explicit by implementing much more complicated validation PyArg_ParseTupleAndKeywords. These names must be written to docs strings manually.

This is a bit confusing to me, but here they go some of my ideas on this (comparing it to other platforms). From what I've read the JVM has no notion of named arguments, meaning that the Kotlin compiler takes care of them when producing the bytecodes for the function call, and has a minimum performance implications at runtime:

Using named arguments produces the same bytecode as using positional arguments. However, changing the order of the arguments leads to the creation of temporary variables. This is because the arguments need to be evaluated in the order they appear, but passed to the method in the original order.

On the other hand, Python bytecode has the notion of Keyword arguments at the bytecode level, so it's the interpreter at runtime who takes care of them, which I guess has some minor performance implication. I would say that when writing native functions that you want to be as fast as possible, preventing a function from being invoked with keyword arguments provides some "nano-improvement".

Thanks to this searching I've found a surprising feature. I already knew that you can use the * symbol in your function signature to force all parameters after it to be passed as named (keyword) arguments, but I did not know that python 3.8 (PEP-570) introduced Positional Only Parameters. Using the / symbol in your function signature, parameters defined before it can only be provided as positional arguments, not as keyword ones.

At first sight it seems like an odd addition. That some builtin functins behave like that is a disturbance for me, so why would I want to disturb others by using that in some of my own functions? Well, there's a pretty good explanation here. Of the 4 reasons given there, the one that really makes this feature useful and valuable to me is the last one:

Since the parameters to the left of / are not exposed as possible keywords, the parameters names remain available for use in **kwargs:

Honestly I'd never thought about that potential problem when using variable number of keyword arguments. When you receive in your packed **kwargs an argument with a name that you already use for your other parameters you get an exception (Exception: [function] got multiple values for argument '[xxx]'), as the interpreter does not know to what parameter that named argument refers to. Let's see an example with the problem and the solution using /



def format_msg(msg: str):
    return f"[[{msg}]]"

def log_call(msg, fn, *args, **kwargs):
    print(f"{fn.__name__} {msg}")
    return fn(*args, **kwargs)
    

# no keywork argument, so it works fine
print(log_call("invoked", format_msg, "hi"))
#format invoked
#Out[11]: 'hi'

# but here we have a problem
try:
    print(log_call("invoked", format, msg="hi"))
except Exception as ex:
    print(f"Exception: {ex}")

# TypeError                                 Traceback (most recent call last)
# Input In [12], in ()
# ----> 1 log_call("invoked", format, msg="hi")
# TypeError: log_call() got multiple values for argument 'msg'


# that we can prevent by redefining the function like this:
def log_call(msg, fn, /, *args, **kwargs):
    print(f"{fn.__name__} {msg}")
    return fn(*args, **kwargs)
    

print(log_call("invoked", format_msg, msg="hi"))
# format_msg invoked
# [[hi]]'


Now that I'm aware of this potential problem in Python a further question arises, how do they manage this in Kotlin? Well, the thing is that they don't have this problem, cause kotlin supports variable number of unnamed arguments, but not of named arguments. The vararg modifier used in a function signature denotes an array of arguments, but there's not an additional modifier for denoting a dictionary of parameters (like python's **). Related to this, the spread operator * only applies to arrays, there's not an equivalent to Python's ** (packing/unpacking) for dictionaries.

Friday, 8 November 2024

Javascript Function.bind

In my previous post I talked about how in Python we have 2 different functions (functools.partial and functools.partialmethod) for using partial function application to functions or methods, due to how callables and bound methods work. A natural question is, what about JavaScript?

JavaScript comes with a Function.prototype.bind function. It allows us to bind a "this" value (thisArg) and other arguments (arg1, arg2...) to a function. When binding values to a function that does not use the "this" value (or just uses it for the 'global this') we can pass null or undefind as thisArg to bind. So Function.prototype.bind will serve us well for binding to a plain function, and for "extracting" a method from a class to use it as a function. I mean:



function format(it1, it2, it3, it4) {
    return `${it1} - ${it2} _ ${it3} . ${it4}`;
}

// function.bind works good for functions 
let fn1 = format.bind(null, "aa", "bb");
console.log(fn1("cc", "dd"));



class Formatter {
    constructor(name) {
        this.name = name;
    }

    format(it1, it2, it3, it4) {
        return `${this.name} + ${it1} - ${it2} _ ${it3} . ${it4}`;
    }
}

//and for a method that we want to "extract" from the class to use as a function 
let format2 = Formatter.prototype.format.bind({name: "Xuan"}, "aa");
console.log(format2("bb", "cc", "dd"));
 

Notice that arrow functions do not have a dynamic 'this', but what used to be called a lexical 'this' (the term seems to have fallen into disuse). They'll search for "this" in their scope chain [1]. This means that trying to bind a "this" value to an arrow function is useless, it will always search "this" in its scope chain. On the other side, binding other parameters to an arrow function is perfectly fine.



// function.bind works fine with arrow functions when binding normal parameters

let greet = (msg, fromX, toY) => `${msg} from ${fromX} to ${toY}`;
console.log(greet.name); //greet
let sayHi = greet.bind(null, "Hi");
console.log(sayHi.name); //bound greet
console.log(sayHi("Xose", "Francois"));
//Hi from Xose to Francois

// but binding "this" will not work. We get a bound function, but the "this" value will not be used by the arrow, it will continue to use the lexical this
let greet2 = (fromX, toY) => `${this.msg} from ${fromX} to ${toY}`;
let info = {msg: "Hi"};
let sayHi2 = greet2.bind(info); 
console.log(sayHi2("Xose", "Francois"));
//undefined from Xose to Francois


Using Function.prototype.bind for binding values to a method (that we'll continue to use as method, not as a function) rather than a normal function is a bit particular. So we have a class with a method that receives several parameters (apart from "this") and we want to bind some of them. Because of Function.prototype.bind expecting us to bind something as "this" we have to invoke bind passing that instance as thisArg and then attach the bound function to the instance itself. That's a bit odd, but OK for binding for a particular instance:



let formatter = new Formatter("Francois");
formatter.format = formatter.format.bind(formatter, "aa", "bb")
console.log(formatter.format("cc", "dd"));


But what if we want the parameter binding for all instances of the class, so that it works for any new instance that we create. For that our best bet is implementing our own partial function.



function partial(fn, ...trappedArgs) {
    return function(...args) {
        return fn.call(this, ...trappedArgs, ...args);
    }
}

// it works fine used with methods
Formatter.prototype.format = partial(Formatter.prototype.format, "aa", "bb")
let formatter2 = new Formatter("Francois");
console.log(formatter2.format("cc", "dd"));

//and when used with plain functions
let fn2 = partial(format, "aa", "bb");
console.log(fn2("cc", "dd"));