top of page
Search
Writer's pictureJack Orenstein

Throwaway functions

Updated: Oct 28, 2023

Suppose you need to read a CSV file and fix the data in one of the columns. Maybe a column has strings that may contain spaces and hyphens that you want to eliminate, e.g. change "ab-cd ef" to "abcdef".


You could put the logic directly into a marcel command. If the column to be fixed is in position 3:


read -c foobar.csv | \
(*row: row[:3] + \
       (row[3].replace('-', '').replace(' ', ''),) + \
       row[4:]))

This is kind of a mess. It would be nice to put the string editing code in a function. One way to do this is to put the function in your .config/marcel/startup.py file:


def remove_dashes_and_spaces(x):
    return x.replace('-', '').replace(' ', '')

and then the command can be simplified:


read -c foobar.csv | \
(*row: row[:3] + \
       (remove_dashes_and_spaces(row[3]),) + \
       row[4:]))

But you probably don't want to clutter up your startup.py file with these functions. An alternative is to define the function in marcel itself. In marcel, you can assign arbitrary python values to variables. This code assigns 7 to x:


x = (3 + 4)

This works because (...) delimits a python function which is evaluated. Marcel allows you to omit the lambda keyword, so this code is equivalent to:


x = (lambda: 3 + 4)

In other words, the parens contains a function of no arguments which computes 3 + 4, and the result is assigned to x.


This technique can be used to create the remove_dashes_and_spaces function:


remove_dashes_and_spaces = (lambda: lambda x: x.replace('-', '').replace(' ', ''))

Both lambdas have to be there. The first one allows the code in the parens to be evaluated, as usual, this time returning the function of interest. Normally, a lambda is assumed if omitted. So this doesn't work:


# BROKEN
remove_dashes_and_spaces = (lambda x: x.replace('-', '').replace(' ', ''))

Because a lambda is present, the code in the parens is evaluated as is, with no arguments, which is incorrect for a function that has one argument.



78 views0 comments

Recent Posts

See All

Compiling Marcel to Python

Marcel is interpreted. A command like this: gen 100 | map (x: (x, x**0.5)) | write gives rise to objects of type marcel.op.Gen,...

Marcel in more places

Thanks to two different pilot errors on my part, I have broken the packaging system of two OSes that package marcel. I would have had no...

Comments


bottom of page