Usage of local-time's make-timestamp macro - date

I'm a beginner with Common Lisp and I'm currently trying out the package local-time.
I'm trying to create a date with the make-timestamp macro which creates an instance of timestamp. I consulted the local-time manual, but I do not understand which arguments I have to supply.
The description of the macro is as follows:
— Macro: make-timestamp &key :day :sec :nsec
Expands to an expression that creates an instance of a timestamp exactly as specified.
Simply using the macro without any arguments makes this happen:
LOCAL-TIME> (make-timestamp)
#2000-03-01T01:00:00.000000+01:00
2000-03-01 is the standard epoch here, so this seems okay so far.
Passing :day 3 as an argument gives me this:
LOCAL-TIME> (make-timestamp :day 3)
#2000-03-04T01:00:00.000000+01:00
Okay. But how can I construct a date from this without having to count days and days into the future from 2000-03-01?
There is also a function called encode-timestamp which appears to do exactly what I want (namely: creating a date by supplying information like the day of the month, month, year, hour, minutes and so on):
LOCAL-TIME> (encode-timestamp 0 0 30 10 13 5 2009)
#2009-05-13T10:30:00.000000+02:00
But then, what is the make-timestamp macro supposed to do?

Make-timestamp is used by several of the encoding functions, including encode-timestamp. I would regard it as rather lowlevel, but it might be of interest to a user of the library.
Encode-timestamp seems to be just the function you want.

Related

libreoffice calc - varargs in macros

I understand Excel has a TEXTJOINfunction which allows one to display multiple values as a tuple.
I also understand Libre Office does - for whatever reason - not have them.
How do I write an auxiliary macro vec that produces the desired tuple representation for me?
E.g. =vec(A1) should produce ="("&A1&")",
=vec(A1:A3) should produce ="("&A1&","&A2&","&A3&")",
=vec(A1,X5:X99,Z3) should result in ="("&A1&","&"X5"&","&X6&...&x99&","&Z3&")"
etc, etc.
Easy enough a macro to implement in, say, bash, but I would like to just define it once then use it in calc, not constantly copy from console to spreadsheet.
How do I implement this in calc?
According to https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=67880, it is possible for a Basic function to use a variable number of arguments if it is declared with Option Compatible. This makes it behave more like MS Excel. The argument is declared as ParamArray pa().
The link that #tohuwawohu posted shows most of the implementation details needed.
To do it in a way that is more native to LibreOffice, write a Spreadsheet Add-In with a Java declaration that uses any[] as an argument. For information about add-in argument types, see https://www.openoffice.org/api/docs/common/ref/com/sun/star/sheet/AddIn.html.
The actual function can also be implemented in Java. Or, it can probably be implemented in another language that accepts a variable number of arguments, such as Python *args.

Is storing sas code in macro variables recommended?

I have to revamp a SAS project in which there are macro variables such as the following:
%let myDate = intnx('month',today(),-1);
and later...
data temp;
a = &myDate;
run;
I'm inclined to use %sysfunc instead:
%let myDate = %sysfunc(intnx(month,%sysfunc(today()),-1));
But I'm wondering... is this a matter of preference or is there some sound reason to prefer one method over the other?
For extremely large datasets, you might find that with this particular example, calling intnx once for every row to get the same value leads to poor performance vs. defining a macro variable once and re-using it indefinitely.
Rob Penridge has demonstrated that in this instance the overhead is likely to be negligible, but for more computationally intensive code this will obviously not always be the case. Your mileage may vary.
More generally, when you start storing code rather than just constants within macro variables, you have to start thinking quite carefully about certain things:
What sort of macro quoting might or might not be required (particularly in a SAS/CONNECT environment when you need to rsubmit blocks of code using macro variables)
Whether or not your macro variable contains semicolons or other characters that might cause unexpected interactions with other blocks of code
Whether it contains macro references that you don't want to resolve until the code executes
You also need to consider the question of timing. If you use %sysfunc() then the function runs when the macro variable is created. If you just store the function call in the macro variable then the function actually does not execute until the data step is running. And in this case since it is calling the today() function it will run for every observation. If you start your data step just before midnight on the last day of the month you could end up with different values of A on different observations in the same dataset.
These are two different things that you are talking about. The first code with %LET and DATA step will create a macro variable myDate without executing the INTNX function, but will create a Table with column a
But, the second revamped %LET statement will actually create just a macro variable with value of INTNX function executed.
So, it actually depends on what the business requirement is -
To create a Table
OR
create a Macro variable which can be created once and used used over and over again.
It's a matter of personal preference. Personally I like to use the %sysfunc approach as it allows me to debug/print the result without having to process any datasteps.
Really I'd say whatever allows for better readability and maintainability. If you're working with people that hate using macros then consider using the simpler first approach. Horses for courses.

Getting the date format for the current locale

When I first stumbled across the constant defaultTimeLocale in System.Locale, I supposed it should contain the default TimeLocale for the current locale.
After some trying around, I realized that it always contains the same constants and looking at the source code of System.Locale quickly revealed that it's in fact only a constant. (Later I realized that the type also tells me that. Since defaultTimeLocale isn't an IO value and doesn't take any arguments it has to be constant.)
What is the way in Haskell to get the current TimeLocale with respect to the current locale?
System.CurrentLocale.currentLocale :: IO TimeLocale
from package current-locale
looks suitable.
I did not test it. Looking at its source code, it should work. I actually do not like it very much since underneath it spawns four date subprocesses (!), which is rather overkill for this simple task, IMHO.
Probably it can be rewritten to use some C or POSIX function instead.

How to add values of two yasnippet fields

I'm trying to write a snippet whose inputs (tab-stop fields) are two numbers, and which returns their sum. But I don't know how to reference the values of both fields at the same time, and it seems like I can't reference the values of the tab-stop within embedded elisp code.
Here is what I tried:
First number: $1
Second number: $2
Sum of two numbers: `(+ (string-to-number $1) (string-to-number $2))`
But when I expand the snippet, the text [yas] elisp error! appears where the sum should go. What am I doing wrong?
joaotavora recently pointed out that this can be done using yas-field-value:
First number: ${1:0}
Second number: ${2:0}
Sum of two numbers: ${2:$(+ (string-to-number (or (yas-field-value 1) "0")) (string-to-number (or yas-text "0")))}
and sorry for the confusion. According to the official snippet writing guide, what you are looking for is called a mirror. Unfortunately, a mirror can only mirror a single variable, so you seem to be out of luck.
This is probably because yasnippet needs to know which mirrors to update when you type a field. (It doesn't want to update them all, because that could be costly), so it needs a way of determining which mirrors are affected by which fields. If it allowed arbitrary substitutions, that would be impossible to determine. (A simple keyword search isn't enough because the variable could be hidden behind metaprogramming).

In lisp how can I measure and capture the time spent evaluating an expression?

I want to capture the results of a call to the time macro in order to gather multiple measurements and process them. I tried to locally setf the standard output and redirect it to a string but it didn't work with the time macro. Maybe it is wrong, but what I tried is:
(with-output-to-string (str)
(let ((*standard-output* str))
(time (test-with-size 40))))
The questions:
Is a way to capture the output of time?
If not, can I capture the slime-profile-report command's output?
If none of the above works, how can I measure the time spent evaluating an arbitrary expression?
What I want to accomplish is to measure the run-time of an algorithm as the size of the input increases so for each input size (ranging from 1 to 100) I will measure a lot of times and keep the average. Then I want to plot the results. Plotting is easy, and I have found many ways in Cliki, but how can I gather the results?
I am using CLISP and CCL.
EDIT: Paul Nathan pointed that the time macro outputs to *trace-output* which is a solution. I would like a nicer, simpler, solution though, because with this one, I have to parse an implementation specific trace.
If you want to capture the text, you need to use the right stream. The ANSI CL standard says that TIME prints to trace output.
So this would give you the text as a string.
(with-output-to-string (*trace-output*)
(time (sin 40.0)))
You could also write your own macro using the time primitives. See 25.1.4.3 Internal Time to get numeric data.