lexi.lambda
2019-12-16 14:02:36

@mflatt Is there any way to get something like regexp-match-peek-positions, except that it’s okay to commit reads up to the point where the match starts? So if the pattern were #px"b+", for example, then if it were applied to a stream of aaaaaaabbbbbbcccc it would commit the reads to each a and start peeking as soon as it sees the first b?


mflatt
2019-12-16 14:16:18

I don’t think there’s anything quite like that, but you might be able to use a peeking wrapper on the port plus an output-port argument to regexp-match to get that effect.


lexi.lambda
2019-12-16 14:21:21

Yes, that makes sense—I’ve been looking at the output-port argument, and I think there’s probably a way to do what I want with it. Thanks!


deactivateduser60718
2019-12-16 16:43:40

[sage@localhost ~]$ racket Welcome to Racket v7.4. > (define externality (make-parameter 0)) > (define control (make-parameter 0)) > (define derived (make-derived-parameter control externality identity)) > (externality 1) > (externality) 1 > (parameterize ([derived 'oops]) (externality)) 'oops > (externality) 'oops > externality does not end up as 0 in sync with derived when control leaves parameterize. Why does the guard for make-derived-parameter not apply when leaving a thread cell?


samth
2019-12-16 16:47:20

parameterize doesn’t set anything when leaving


deactivateduser60718
2019-12-16 16:48:47

Yeah, I got that far, but my question is why setting a value is the only trigger for the guard.


deactivateduser60718
2019-12-16 16:49:05

Is there a way to capture both setting a value and a transition between thread cells?


samth
2019-12-16 16:49:53

what do you mean by “transition between thread cells”


samth
2019-12-16 16:50:14

parameterize doesn’t set anything in either direction


deactivateduser60718
2019-12-16 16:51:31

Maybe I should just rephrase to ask what I need to do to make (externality) be 0 as a side-effect of control leaving parameterize.


deactivateduser60718
2019-12-16 16:52:04

Is that possible?


samth
2019-12-16 16:52:34

no, control leaving parameterize doesn’t have any effect on anything


deactivateduser60718
2019-12-16 16:52:43

Ok. Thank you


samth
2019-12-16 16:53:16

but having a derived parameter where the guard does mutation seems like a worrying approach in general


deactivateduser60718
2019-12-16 16:53:51

I know. I’m trying to figure out a backwards-compatible way of splitting one parameter that controls several paths on the filesystem.


deactivateduser60718
2019-12-16 16:54:36

Right now I have a parameter that holds a complete path, which changes the output of several other path building functions.


deactivateduser60718
2019-12-16 16:55:47

If I want to have some of those functions return output relative to an entirely different path, then the most obvious approaches introduce breaking changes since they no longer use the original parameter.



deactivateduser60718
2019-12-16 17:03:29

Unless there’s a way to instruct Racket to change the values of several parameters in sync in a way that isn’t weird, it seems my only approach is to instruct people to conditionally ignore parts of the API.


samth
2019-12-16 17:05:02

I think using the accessor wrapper to make it look like the parameter changed without changing it is the way to go


deactivateduser60718
2019-12-16 17:05:48

That’s a good idea. I’ll see how I can leverage that.


deactivateduser60718
2019-12-16 17:44:11

@samth Here’s how I interpreted your advice. I think this should work well. (define (derive-path-parameter conventional-directory) (make-derived-parameter (make-parameter #f) (λ (v) v) (λ (v) (or v (build-path (polyglot-project-directory) conventional-directory)))))


samth
2019-12-16 17:46:44

Yes, that’s what I was thinking


ardit.berisha01
2019-12-16 18:43:29

@ardit.berisha01 has joined the channel


anything
2019-12-16 19:52:45

I think it wouldn’t be easy to provide a minimal program reproducing the behavior in this question, so I don’t know how useful this request for help will be.

The main “thread” of my application has the following function. This function just atomically sets a list of data (from an SQL server).

(define *db* (box #f))

(define (in-memory-db-set! db) (set-box! *db* db) (unbox *db*))

I have the following bug that occurred at least once. An update procedure increments the database then calls in-memory-db-set! to refresh the database — so the main “thread” now uses the refreshed database. The update procedure is run in a thread spawned by the library deferred. For the first time, I noticed that at least once data were arriving but nobody could see them on the web. I turned off the caching mechanism (to avoid querying the SQL server all the time) and the missing data appeared on the web.

The only point of failure I could think of is that the update procedure somehow refreshes the database with… (in-memory-db-set! (get-programs-and-activities-all)) (printf "Database refreshed.~n") (printf "Update completely done.~n") … but perhaps the main “thread” doesn’t notice it. Is that at all possible? (This works most of the time. This application has been running for a month at least and nobody has noticed anything wrong.) (In my life, threads are always what makes my life miserable. I never seem to really understand how to avoid all the pitfalls with it, so I’m inclined to think they’re biting me again, but I don’t know where the problem is.)

This is a web application using web-server/servlet. (That’s why I’m using box, set-box!, unbox.) Any suggestions or moral support is welcome!


philip.mcgrath
2019-12-17 02:48:31

One problem is that your in-memory-db-set! is not, in fact, atomic, as another thread could act between set-box! and unbox. Conventional alternatives include atomic compare-and-set with box-cas! or to implement a lock with a semaphore, or you could have a dedicated thread in charge of the state and use synchronizable events to communicate with it. (I found the paper “Kill-Safe Synchronization Abstractions” very helpful in learning about Racket’s concurrency system: https://www.cs.utah.edu/plt/publications/pldi04-ff.pdf) At a higher level, you have to decide what behavior you want in the face of concurrency, especially concurrent writes.


josh.mcgrath08
2019-12-17 04:31:26

@josh.mcgrath08 has joined the channel


sorawee
2019-12-17 07:34:22

I suppose Racket class doesn’t support static method. Do I understand this correctly?


sorawee
2019-12-17 07:41:30

In particular, it’s a common pattern in other OOP langs to have a static method like fromX to create an instance from X. Is there an idiomatic equivalent in Racket? Just create a function named fromX ?