samth
2019-4-15 15:43:50

This program has a surprising-to-me error: #lang racket (define-syntax (m stx) (syntax-case stx () [(_ e1 ) (local-expand #'e1 'module null)])) (m (define x 1)) It says: define-values: not allowed in an expression position. But where is the expression position?


lexi.lambda
2019-4-15 16:28:51

@samth You can’t expand define-values, enclosing contexts always partial expand and discover define-values, then handle the definition themselves (so define-values never handles itself). But I imagine you already knew that, so is the point you’re making just that the error message is confusing?


notjack
2019-4-15 16:54:47

it’s very confusing


lexi.lambda
2019-4-15 17:08:59

It could be changed to say something along the lines of “cannot be expanded directly, only partially expanded”, but ultimately the confusion of how definitions in general work seems hard to avoid (since the notion of partial expansion is a little non-obvious).


notjack
2019-4-15 18:36:31

I think the underlying source of confusion is that m looks like it ought to be an identity macro of some sort, but (m (define ...)) doesn’t work in places where (define ...) works


lexi.lambda
2019-4-15 18:52:27

If m just expanded to e1, it would work fine, so I’m not sure what you mean by that.


notjack
2019-4-15 18:56:42

What I mean is, I think of local-expand as something that changes when expansion occurs, but not something that changes the result of expansion. So if the only thing a macro does is local-expand, with nothing else going on whatsoever, I would intuit that it’s not doing anything at all and should act like an identity function.


lexi.lambda
2019-4-15 19:05:03

That is what I meant by “the notion of partial expansion is a little non-obvious”.


notjack
2019-4-15 19:09:32

Yes. I gather that this intuition does not work here. I’m saying that it’s a shame it doesn’t, and that the fact that it doesn’t is confusing.


ben
2019-4-15 19:11:39

anyone know how to find the numbers of seconds in a day using gregor? I’ve been looking for a function f where (f (days 1)) gives the right number


notjack
2019-4-15 19:12:01

@ben I think you can’t, in general


ben
2019-4-15 19:13:13

No way. I’m not looking for the number of seconds in April 15th 2019. I just to know “how many seconds in 24 hours”?


notjack
2019-4-15 19:14:28

but one day is not always equal to 24 hours


soegaard2
2019-4-15 19:15:16

Can period-between be used?


notjack
2019-4-15 19:17:27

wait, nevermind I’m confused now: > Gregor assumes that all days have exactly 86,400 seconds. Therefore, it is based fundamentally on mean solar time, or Univeral Time, and not on Coordinated Universal Time (UTC), the civil time scale adopted by most of the world. In the interest of reconciling the SI second to a close approximation of mean solar time, UTC occasionally inserts an extra leap second into a day.


soegaard2
2019-4-15 19:18:48

wait, why are you confused now - you found the answer.


ben
2019-4-15 19:19:06

no! 86400 is not the answer I want


notjack
2019-4-15 19:19:12

I’m confused because I remember opening a github issue asking about this and getting a different answer of some sort


soegaard2
2019-4-15 19:19:42

@ben I know, so the answer is “no” :wink:


ben
2019-4-15 19:19:43

but that’s funny about the docs — I was thinking @notjack was right and I should use a constant instead of going through gregor


ben
2019-4-15 19:20:11

I don’t think period-between works


notjack
2019-4-15 19:20:28

lexi.lambda
2019-4-15 19:20:44

I don’t understand why 86,400 is not the answer you want


soegaard2
2019-4-15 19:21:03

leap seconds!


lexi.lambda
2019-4-15 19:21:27

But if ben is explicitly not looking for the number of seconds on a particular day, then how are leap seconds relevant?


soegaard2
2019-4-15 19:21:35

good point!


notjack
2019-4-15 19:21:40

Oh wait, now I know why this is relevant: daylight savings time


lexi.lambda
2019-4-15 19:21:53

Even then, that would involve a specific day


lexi.lambda
2019-4-15 19:22:16

Unless @ben is just saying he doesn’t want to write the magic number “86,400” in his code


lexi.lambda
2019-4-15 19:22:49

In that case, I think @soegaard2 is right, and period-between can get you there


notjack
2019-4-15 19:22:52

my assumption is that a function f from date-period? to a number of seconds shouldn’t break the invariant that adding the original date period to a moment gives the same answer as adding (seconds (f p)) does


ben
2019-4-15 19:23:49

but period-between expects datetimes, not periods


lexi.lambda
2019-4-15 19:24:31

Yes, you have to indirect through a date, since although days are always 86,400 seconds long, the same does not hold for other time units


lexi.lambda
2019-4-15 19:25:08

So you couldn’t have an operation that, say, converts (months 1) into seconds without knowing a specific month (since months vary in length)


lexi.lambda
2019-4-15 19:26:20

But if you’re relying on the assumption that all days have the same length, anyway (which you are, since you’re using a constant instead of recalculating it as-needed), then you can just make two datetimes exactly one day apart and use period-between on that.


ben
2019-4-15 19:28:27

ok thanks everyone


jaz
2019-4-15 19:38:29

@ben Number of seconds in a local day, then?


jaz
2019-4-15 19:38:44

You should be able to get that. Lemme take a look.


jaz
2019-4-15 19:39:10

(Sorry, mentioned the wrong Ben initially.)


ben
2019-4-15 19:41:05

number of seconds in (hours 24) would be ok too


jaz
2019-4-15 19:41:08

But, to be clear: - Gregor does not do proper UTC, so leap seconds won’t be counted. - A local date can have a number of seconds different from 86,400.


jaz
2019-4-15 19:41:25

That would always have to be 86,400. (Wow, I keep tagging the wrong Ben. I Slack poorly.)


jaz
2019-4-15 19:42:24

I think time-periods should be able to get you that info. But sometimes I forget what functionality is in gregor and what is in an unreleased successor to gregor. I’ll check on all of this.


jaz
2019-4-15 19:46:09

Huh. Looks like that function does not exist in gregor. I was looking for a time-period->seconds, which is a perfectly sensible function (unlike date-period->seconds which would be nonsense, unless you anchored the period to a particular date in a particular zone).


jaz
2019-4-15 19:49:45

Yeah, datetime-lib (again, unreleased) has a time-period->nanoseconds. I don’t see any reason not to add that to gregor, too.


jaz
2019-4-15 19:49:58

Right now, I think the only way to get this is: > (require gregor/period) > (period-between (datetime 2000 1 1) (datetime 2000 1 2) '(seconds)) #<period of 86400 seconds>


jaz
2019-4-15 19:50:03

which others have mentioned


jaz
2019-4-15 19:50:28

(And which is clearly not convenient.)


notjack
2019-4-15 20:17:28

@jaz why would date-period->seconds be unreasonable, exactly? Since date periods seem unrelated to any fixed point in time and leap seconds are ignored


jaz
2019-4-15 20:20:19

Because I wouldn’t want these two things to produce different results: - (+date-period date-provider date-period) - (+ seconds date-provider (date-period->seconds date-period))


jaz
2019-4-15 20:21:01

What it comes down to is that a date-period does not represent something that can be reduced to a number of seconds, unless you anchor it.


jaz
2019-4-15 20:21:13

How many seconds are there in a month?


notjack
2019-4-15 20:31:44

@jaz Are there ever points in time where (+time-period d (hours n)) is not equal to (+time-period d (seconds (* 60 n)))? Like, due to daylight savings time or something?


jaz
2019-4-15 20:32:22

Nope


jaz
2019-4-15 20:33:15

All time periods are reducible to nanoseconds, because of the “we do not care about leap seconds” rule.


notjack
2019-4-15 20:33:49

I think I’m just confused about what date periods are exactly. They don’t seem to be anchored to any points in time, but they also don’t represent a fixed amount of time because adding (days 1) is not always the same as adding (hours 24)


jaz
2019-4-15 20:33:54

Daylight savings time doesn’t change the number of seconds in a minute or hour, or anything like that.


jaz
2019-4-15 20:34:26

@notjack That’s right. They represent abstract quantities which can be added to concrete date-providers.


jaz
2019-4-15 20:36:59

They are also the result of a period-between, which starts with two concrete items. But this is admittedly more problematic. And gregor in fact handles this poorly. Witness: > (period-between (date 2000 1 1) (date 2000 1 2) '(seconds)) #<period [empty]>


jaz
2019-4-15 20:37:20

The correct response is to reject the question, not to give a baffling answer.


soegaard2
2019-4-15 20:38:30

Ok, that answer doesn’t make sense.


notjack
2019-4-15 20:44:05

This is so weird to me because it’s not like other cases I think of as similar, like converting between yards and inches, where there’s two different abstract units for the same conceptual dimension. Here’s there’s two distinct dimensions of time, where one is seconds and the other is these weird calendar days. They’re not measuring the same thing at all.


jaz
2019-4-15 20:44:27

That’s exactly right.


notjack
2019-4-15 20:46:05

What if we just…. never used date periods?


jaz
2019-4-15 20:46:36

There’s no requirement to


jaz
2019-4-15 20:46:57

But I’m not going to get rid of date arithmetic, because that’s genuinely useful.


jaz
2019-4-15 20:47:05

Even though it’s weird.


notjack
2019-4-15 20:47:37

yeah for things like recurring schedules it does make sense


notjack
2019-4-15 20:48:43

I don’t want “do this every seven days, starting at midnight on this day” to oscillate back and forth between actually doing it at midnight and doing it at 1AM / 11PM based on how daylight savings time works out


jaz
2019-4-15 20:49:05

I should mention that the above example from gregor isn’t problematic in datetime-lib, because there are separate date-period-between, time-period-between, and period-between functions, which have contracts limiting their use.


notjack
2019-4-15 20:50:59

I think a period like (period [days 11] [seconds 42]) is weird because it’s implying that these units are compatible somehow


jaz
2019-4-15 20:53:06

Yeah, and we could just completely separate date and time periods. That might be better.


notjack
2019-4-15 20:55:14

Calling them date periods and time periods but not unifying them is also kind of confusing, because it makes you wonder why there aren’t generic period operations. Maybe if they were just called completely separate things?


jaz
2019-4-15 20:56:11

Makes sense


notjack
2019-4-15 20:58:40

What do datetime libraries in other languages usually call these things? I think time-period is roughly equivalent to java.time.Duration


jaz
2019-4-15 21:00:59

Yeah, java.time has separate notions of Period and Duration, which roughly correspond to date and time periods in gregor.


notjack
2019-4-15 21:02:33

hmmm, and they do have a common TemporalAmount interface and they specify that Duration assumes fixed 24-hour days while Period doesn’t (because it doesn’t represent fractions of days at all)