Re: [racket-users] Generics: delegate to a parent

2019-03-22 Thread zeRusski

>
> object system (which also cooperates with generics)


TBH I've been avoiding Racket object system since my needs are typically 
limited and don't call for full blown OOP. I only casually looked at what 
its capable of, I guess may need to revisit. I was rather hoping for 
something as simple as structs and generics a-la Emacs Lisp. Superficially 
Racket structs appear to be like those in Emacs Lisp and Clojure, but now 
that I'm using them more I'm starting to doubt that. They feel lower level 
(although quite rich) - the kind of cloth you use to build everything else. 
I feel like Racket could use a more nimble data type with identity than 
structs, yet not as ad-hoc as hash-tables. Well, nothing stops one from 
implementing that, I suppose.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Thread safe operations and shared memory

2019-03-22 Thread zeRusski
Racket documentation doesn't tell much on the subject. The only two things 
I've found are *box-cas! *and this passage from Evaluation Model that to me 
remains a bit cryptic.

Threads are created explicitly by functions such as thread 
> .
>  
> In terms of the evaluation model, each step in evaluation actually consists 
> of multiple concurrent expressions, up to one per thread, rather than a 
> single expression. The expressions all share the same objects and top-level 
> variables, so that they can communicate through shared state, and 
> sequential consistency is guaranteed (i.e., the result is consistent with 
> some global sequence imposed on all evaluation steps across threads). Most 
> evaluation steps involve a single step in a single expression, but certain 
> synchronization primitives require multiple threads to progress together in 
> one step.


Could someone illuminate how I should be thinking about mutation in 
presence of multiple green threads? E.g. mutate shared mutable hash-table, 
mutate mutable hash-table held in in a struct field? Basically, I'm trying 
to decide when to reach for mailboxes and other synchronization primitives. 
If I'm ok with "eventually" other threads will see that value, should I 
think hard about mutating things?

What's comparable to Clojure atoms? Would it be boxes + box-cas!?

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Thread safe operations and shared memory

2019-03-22 Thread George Neuner


On 3/22/2019 7:01 AM, zeRusski wrote:
Racket documentation doesn't tell much on the subject. The only two 
things I've found are *box-cas! *and this passage from Evaluation 
Model that to me remains a bit cryptic.


Threads are created explicitly by functions such as thread

.
In terms of the evaluation model, each step in evaluation actually
consists of multiple concurrent expressions, up to one per thread,
rather than a single expression. The expressions all share the
same objects and top-level variables, so that they can communicate
through shared state, and sequential consistency is guaranteed
(i.e., the result is consistent with some global sequence imposed
on all evaluation steps across threads). Most evaluation steps
involve a single step in a single expression, but certain
synchronization primitives require multiple threads to progress
together in one step.



That passage has to do with how the Racket virtual machine handles 
threads - the code generated for threads is required to include 
synchronization points where the thread can be safely halted if 
necessary - e.g., for a context switch, or for GC, etc.  The compiler 
does this automatically, so you don't need to worry about it.



Could someone illuminate how I should be thinking about mutation in 
presence of multiple green threads? E.g. mutate shared mutable 
hash-table, mutate mutable hash-table held in in a struct field? 
Basically, I'm trying to decide when to reach for mailboxes and other 
synchronization primitives. If I'm ok with "eventually" other threads 
will see that value, should I think hard about mutating things?


Racket's threads are preemptively multi-tasked, so you do need to 
synchronize access to shared data structures while they are being 
mutated to avoid readers seeing partial updates.  Also be aware that 
Racket threads do not make use of multiple cores ... to leverage 
multiple cores you need to use either futures or places.


Message passing avoids most share locking issues, so it is better to 
implement that way when possible.




What's comparable to Clojure atoms? Would it be boxes + box-cas!?


Yes, Racket's boxes are analogous to Clojure's atoms.

At present, any update (set!) of a box, an mcons, or a struct field is 
atomic WRT threads - the *current* Racket virtual machine will not 
permit a thread switch while these things are happening.  Going forward 
things might change with the move to Racket-on-Chez, so best always to 
use deliberate synchronization when you mutate shared data.


George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] color-maps for the plot package

2019-03-22 Thread Jens Axel Søgaard
Looks great.


Den tor. 21. mar. 2019 kl. 14.01 skrev Alex Harsanyi :

>
> I created a pull request for items (1) and (2), illustrating the changes
> that I propose, you can find it here:
>
> https://github.com/racket/plot/pull/52
>
> Alex.
>
> On Wednesday, March 20, 2019 at 12:17:47 PM UTC+8, Alex Harsanyi wrote:
>>
>>
>>
>> On Wednesday, March 20, 2019 at 10:35:51 AM UTC+8, Ben Greenman wrote:
>>>
>>> > Could you (or Ben or Matt) elaborate on how do you see this work for
>>> non
>>> > plot programs?
>>>
>>> I'm thinking a color-map% object would define a possibly-infinite
>>> sequence of colors that look nice in some way. The colors might be
>>> useful anywhere where someone wants a "rainbow" of colors ... maybe
>>> for:
>>>
>>> - fonts in a slideshow (colorblind-friendly? grayscale-friendly?),
>>> - coloring the error messages made by a linter or program analyzer,
>>> - drawing a sunset, etc.
>>>
>>
>> The examples listed above might be better served by other color choosing
>> mechanisms, for example, I have implemented some color manipulation code
>> based
>> on https://tallys.github.io/color-theory/, you can find it here:
>> https://github.com/alex-hhh/data-frame/blob/master/private/colors.rkt .
>> In
>> particular the `pick-color` function might do something similar to what
>> Pyret
>> is using (as suggested by Justin Zamora).
>>
>> Other solutions are also possible, including using gradient color maps,
>> but
>> this is a larger scope that I originally planned for and I don't have
>> the time to prepare and submit a patch for such changes.
>>
>> My proposal is more limited, to allow plot users to produce good looking
>> plots
>> with minimum effort.  What I propose is:
>>
>> (1) Add a mechanism (via parameters) to replace the `pen-colors` and
>> `brush-colors` vectors in the plot package with custom defined colors.
>> This
>> means that the existing `->pen-color` and `->brush-color` functions would
>> now
>> return a different color depending on what `pen-colors` or `brush-colors`
>> are
>> installed.  This also has the benefit that the existing mechanism of
>> specifying numbers for colors will now work with color maps:
>>
>> (plot (list (function sin -5 5 #:color 1)))
>>
>> (2) "Borrow" the qualitative color maps from matplotlib, so the user has
>> some
>> nice predefined set of colors to choose from for their plots.
>>
>> Also, possibly the following backwards incompatible changes:
>>
>> (3) change the default set of `pen-colors` and `brush-colors` to one of
>> the
>> new color maps, so the nicer colors are on by default.
>>
>> (4) change the default plot behavior so that a different color is chosen
>> for
>> each renderer, this means that things like the code below would result in
>> different colors used for the `sin` and `cos` functions:
>>
>> (plot (list (function sin -5 5) (function cos -5 5)))
>>
>> If others think that (1) and (2) are worthwhile doing, I will submit a
>> PR, so
>> we can discuss the API an implementation over something more concrete.  I
>> am
>> open discussion for points (3) and (4).
>>
>> For the more broader color map changes, if the improvements are split up
>> in
>> small incremental tasks, I will be happy to help out, as time allows.
>>
>> Alex.
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>


-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Thread safe operations and shared memory

2019-03-22 Thread Greg Hendershott
I think this is a pretty good overview of the "stock" choices:

  https://docs.racket-lang.org/guide/concurrency.html

On Fri, Mar 22, 2019 at 8:21 AM George Neuner  wrote:
> Message passing avoids most share locking issues, so it is better to 
> implement that way when possible.

I agree. Usually I start with a channel or async-channel. And usually
that turns out to be all I think need.

If you really need to, you can build things using semaphores, but
that's tricky and I'd suggest something like:

  http://greenteapress.com/wp/semaphores/

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Thread safe operations and shared memory

2019-03-22 Thread zeRusski
Thank you George for thorough explanation. 

(set!) of a box, an mcons, or a *struct field* is atomic WRT threads


So, the `foo-struct-set!` would be atomic, but (hash-set! 
(foo-struct-field-with-table foo) key value) would not (assuming a mutable 
hash-table value there), correct?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Error handling for the GUI

2019-03-22 Thread James Platt
I'm working on displaying informative error messages in a GUI and I have been 
finding that many of the things I need to handle are contract violations in 
downstream functions.  The thing is that it seems like there ought to be a 
better way than the methods I can think of.  

It's very simple to use the predicate exn:fail:contract? to tell if there was a 
contract violation but this doesn't tell me which downstream function or which 
parameter caused the error.  I could parse the full error message with regular 
expressions and use that to build my error message for the user.  However, this 
turns out to be a lot of code and it also seems like it could break down if a 
future update to Racket or some package changes the wording of an error 
message.  I could go to the downstream functions, remove their contracts and, 
instead, have them raise custom exceptions.  Then catch those exceptions in the 
GUI code.  Not only is this a lot of code to change but it seems wrong to start 
with code created according to good practice and then undo it for further 
improvement.  

So my question is whether there is a better way to do this than I am aware of?

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Thread safe operations and shared memory

2019-03-22 Thread Matthew Flatt
At Fri, 22 Mar 2019 08:21:15 -0400, George Neuner wrote:
> At present, any update (set!) of a box, an mcons, or a struct field is 
> atomic WRT threads - the *current* Racket virtual machine will not 
> permit a thread switch while these things are happening.  Going forward 
> things might change with the move to Racket-on-Chez, so best always to 
> use deliberate synchronization when you mutate shared data.

While I agree with the recommendation to use synchronization
constructs, I'd like to clarify that this guarantee --- and the
stronger one about sequential consistency --- will not change with
respect to the notion of "thread" that is provided by the `thread`
function.

The guarantee of sequential consistency currently doesn't apply to
Racket's futures or mutation of shared byte strings across Racket's
places. It's possible that future versions of Racket will have
additional concurrency constructs without sequential consistency, but
we won't use the word "thread" for any such construct.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Thread safe operations and shared memory

2019-03-22 Thread Matthew Flatt
At Fri, 22 Mar 2019 12:13:13 -0700 (PDT), zeRusski wrote:
> So, the `foo-struct-set!` would be atomic, but (hash-set! 
> (foo-struct-field-with-table foo) key value) would not (assuming a mutable 
> hash-table value there), correct?

Hash tables can be safely updated by `hash-set!` even when they are
used by multiple threads, but with the caveat that `hash-set!` is not
kill-safe for `equal?`-based tables. Not being "kill-safe" means that
an `equal?` hash table can get stuck in locked state if you kill a
thread that is in the middle of a `hash-set!` or `hash-ref`. (Hash
table update and reference is kill-safe for `eq?`- and `eqv?`-based
hash tables.)

Hash table operations like `hash-map` are not atomic with respect to
hash-table updates, but there are still some weak guarantees. See the
docs for more information.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Error handling for the GUI

2019-03-22 Thread James Platt
Well, I might make some kind of compromise.  What I don't want to allow is the 
possibility of the user experience being "I click on the button and nothing 
happens."  Next worst is to display a raw error message which the user can only 
interpret by cutting and pasting it into a web search.  So yes, I could just 
get that far and then try and fix all the bugs rather than try and handle every 
possible exception gracefully.  More likely, meet somewhere in the middle of 
those approaches.  


On Mar 22, 2019, at 4:55 PM, Robby Findler wrote:

> I know this will sound silly, but you could just consider them bugs and the 
> fix them? (I went through a similar thought process with DrRacket years ago 
> and that was the conclusion I came to-- just slap an "internal error" message 
> on it so people aren't confused about it being a bug in their program.)
> 
> Robby
> 
> On Fri, Mar 22, 2019 at 3:09 PM James Platt  wrote:
> I'm working on displaying informative error messages in a GUI and I have been 
> finding that many of the things I need to handle are contract violations in 
> downstream functions.  The thing is that it seems like there ought to be a 
> better way than the methods I can think of.  
> 
> It's very simple to use the predicate exn:fail:contract? to tell if there was 
> a contract violation but this doesn't tell me which downstream function or 
> which parameter caused the error.  I could parse the full error message with 
> regular expressions and use that to build my error message for the user.  
> However, this turns out to be a lot of code and it also seems like it could 
> break down if a future update to Racket or some package changes the wording 
> of an error message.  I could go to the downstream functions, remove their 
> contracts and, instead, have them raise custom exceptions.  Then catch those 
> exceptions in the GUI code.  Not only is this a lot of code to change but it 
> seems wrong to start with code created according to good practice and then 
> undo it for further improvement.  
> 
> So my question is whether there is a better way to do this than I am aware of?
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Error handling for the GUI

2019-03-22 Thread Alex Harsanyi

On Saturday, March 23, 2019 at 5:17:22 AM UTC+8, James Platt wrote:
>
> Well, I might make some kind of compromise.  What I don't want to allow is 
> the possibility of the user experience being "I click on the button and 
> nothing happens."  


You can wrap each button callback with a `with-handlers` call that displays 
a message box when an exception is raised inside the callback, but this 
user interface might not be very pleasant to use.  Also this will not help 
you if your callback does something like:

(when #f 
   ;; rest of the code here
   )
 

> Next worst is to display a raw error message which the user can only 
> interpret by cutting and pasting it into a web search.  


If the user can do nothing about this error except report it back to the 
developer, you can just log this error to a file, display an "Internal 
Error" dialog box and instruct the user to add the log file to their bug 
report.
 

> So yes, I could just get that far and then try and fix all the bugs rather 
> than try and handle every possible exception gracefully.


If you have a limited amount of time available, I would suggest you spend a 
little of that time on code that displays "Internal Error" and most of that 
time in detecting and fixing these bugs.  You won't be able to fix all of 
them, but you can go a long way of making the "Internal Error" dialog box 
be a rare occurrence in your application.

You should display more information to the user, only if the user can 
actually do something to fix the problem (e.g if you cannot open a file, 
tell the user which file you cannot open), otherwise your application 
should just log the exception into a file, along with other debugging 
information so you can reproduce the problem, than instruct the user to 
report a bug and attach the log file.
 

>  More likely, meet somewhere in the middle of those approaches.   
>
>
> On Mar 22, 2019, at 4:55 PM, Robby Findler wrote: 
>
> > I know this will sound silly, but you could just consider them bugs and 
> the fix them? (I went through a similar thought process with DrRacket years 
> ago and that was the conclusion I came to-- just slap an "internal error" 
> message on it so people aren't confused about it being a bug in their 
> program.) 
> > 
> > Robby 
> > 
> > On Fri, Mar 22, 2019 at 3:09 PM James Platt  > wrote: 
> > I'm working on displaying informative error messages in a GUI and I have 
> been finding that many of the things I need to handle are contract 
> violations in downstream functions.  The thing is that it seems like there 
> ought to be a better way than the methods I can think of.   
> > 
> > It's very simple to use the predicate exn:fail:contract? to tell if 
> there was a contract violation but this doesn't tell me which downstream 
> function or which parameter caused the error.  I could parse the full error 
> message with regular expressions and use that to build my error message for 
> the user.  However, this turns out to be a lot of code and it also seems 
> like it could break down if a future update to Racket or some package 
> changes the wording of an error message.  I could go to the downstream 
> functions, remove their contracts and, instead, have them raise custom 
> exceptions.  Then catch those exceptions in the GUI code.  Not only is this 
> a lot of code to change but it seems wrong to start with code created 
> according to good practice and then undo it for further improvement.   
> > 
> > So my question is whether there is a better way to do this than I am 
> aware of? 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups "Racket Users" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an email to racket-users...@googlegroups.com . 
> > For more options, visit https://groups.google.com/d/optout. 
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Generics: delegate to a parent

2019-03-22 Thread Matthew Butterick


> On Mar 21, 2019, at 9:55 AM, Kees-Jochem Wehrmeijer  wrote:
> 
> It does? That sounds interesting. Do you have an example of that, or could 
> you point me to some docs? I thought object methods were called with send or 
> send-generic. 

Yes, you can attach generic interfaces to classes. Technique described here:

https://groups.google.com/d/msg/racket-users/uKPauoZvZQo/uey0a66HBgAJ 



> On Mar 22, 2019, at 3:34 AM, zeRusski  wrote:
> 
> TBH I've been avoiding Racket object system since my needs are typically 
> limited and don't call for full blown OOP. I only casually looked at what its 
> capable of, I guess may need to revisit. I was rather hoping for something as 
> simple as structs and generics a-la Emacs Lisp. Superficially Racket structs 
> appear to be like those in Emacs Lisp and Clojure, but now that I'm using 
> them more I'm starting to doubt that. They feel lower level (although quite 
> rich) - the kind of cloth you use to build everything else.


My understanding is that Racket structs are comparatively more foundational 
(e.g., "_all_ values in Racket are structs" [2]), but for that reason, are 
comparatively more rigid. 

Furthermore, "classes and objects are implemented in terms of structure types." 
[3] So even though I am typically an OOP resister, I've come to think of 
Racket's class system as a friendlier way of working with Racket structs.

[2] https://groups.google.com/d/msg/racket-users/7rKKh088zEg/EeuJ3VbSBQAJ 


[3] https://docs.racket-lang.org/guide/define-struct.html 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: Pretty display of tabular data?

2019-03-22 Thread travis . hinkelman
I just came across a post  on 
tabular data structures in R, Python, and SQL. The post is written has a 
friendly intro to the subject, which the author claims is a gap that needs 
filling. Thus, the post might not contain much information that is new to 
this group. Perhaps the opportunity is for the Racket community to use that 
friendly intro as a springboard to a comparison for how to approach tabular 
data in Racket.



On Saturday, March 16, 2019 at 3:54:51 PM UTC-7, jackh...@gmail.com wrote:
>
> Hooray! Now we're up to 7 tagged packages 
>  (that was fast!)
>
> On Saturday, March 16, 2019 at 12:13:38 PM UTC-7, johnbclements wrote:
>>
>> Yep, excellent idea. I’ve added the ’tabular’ tag to csv-writing. 
>>
>> John 
>>
>> > On Mar 15, 2019, at 3:24 AM, jackh...@gmail.com wrote: 
>> > 
>> > I think we should all work towards making our existing code in this 
>> area more discoverable, so we can get a better sense of what libraries for 
>> working with tables exist in the wild. To those of you who own Racket 
>> packages that provide any functionality related to data tables: I recommend 
>> adding the "tabular" tag to your package's description in the package 
>> catalog. There's no need to remove more-specific tags (like "data-frame") 
>> from your package, but even if you have a more specific tag please include 
>> the general "tabular" tag so it's easy to search for your package. So far 
>> there's only 3 packages tagged with "tabular" (and one of those is a 
>> package of mine that I just tagged while writing this post). I see several 
>> packages that are good candidates for the tag: 
>> > • data-frame 
>> > • sqlite-table 
>> > • table-panel 
>> > • tabular 
>> > • rml-core (maybe?) 
>> > • sinbad 
>> > • spmatrix (maybe?) 
>> > • spreadsheet-editor 
>> > • csv 
>> > • csv-reading 
>> > • csv-writing 
>> > • simple-csv 
>> > • Most things with the "sql" tag 
>> > The more packages we have tagged and documented, the easier it will be 
>> to find real code using tables in the wild. Which is information we'll need 
>> if we want to understand how a standard `racket/table` API might look. 
>> > 
>> > On Thursday, March 14, 2019 at 10:28:41 AM UTC-7, Ryan Kramer wrote: 
>> > On Thursday, March 14, 2019 at 12:26:39 AM UTC-5, Alex Harsanyi wrote: 
>> > 
>> > There are now several projects announced on this list, all of them deal 
>> with 
>> > data analysis on one way or the other.  Would it be possible to join 
>> forces 
>> > and merge these projects so that we end up with one library that 
>> servers 
>> > multiple purposes equally well?  Something where the final product is 
>> greater 
>> > than the sum of its parts... 
>> > 
>> > Or perhaps these libraries have aims that are so different from each 
>> other 
>> > that the only thing they share is a very abstract concept of "table"? 
>> > 
>> > I think my project "plisqin" is one of those you are thinking of. 
>> Matt's "tbl" is also one. I'm also keeping an eye on Ryan's "sql". Are 
>> there any more you were thinking of? 
>> > 
>> > Regarding joining forces/merging these projects, this is a good 
>> question that I think warrants discussion. So I'll share my thoughts. 
>> > 
>> > Obviously I can't speak for all of us, but right not I only see the 
>> "very abstract concept of "table"" as potential shared code. (Also, 
>> learning about snip% earlier in this thread was awesome. I'd love to use 
>> something like that in my project.) 
>> > 
>> > I think the differences between plisqin and tbl are fairly obvious - 
>> plisqin is an alternative to SQL while tbl is an alternative to 
>> "Python/NumPy/SciPy, or R/Tidyverse (or, horrors, plain R)" 
>> > 
>> > Now comparing Ryan's sql to plisqin is a different story. These 
>> projects are both alternatives to SQL. But I think there is enough 
>> difference between our approaches and scope to warrant separate projects, 
>> at least for now. 
>> > 1) sql seems to be mostly implemented as macros. plisqin is mostly 
>> implemented as procedures. 
>> > 2) plisqin has some design decisions that some might consider "too much 
>> magic", namely inline joins and "inject-able aggregates" (need better name) 
>> as documented here: https://docs.racket-lang.org/plisqin/intro.html. 
>> Whereas sql-the-package seems to more closely mirror SQL-the-language - it 
>> would be difficult to surprise yourself with the SQL you generate. 
>> > 3) I am trying to design #lang plisqin so that people with no Lisp 
>> experience can use it. (Whether I will succeed is another matter...) 
>> > 
>> > I apologize to Ryan C if I have mischaracterized sql. I'd like to have 
>> a longer conversation about this, but maybe this list is not the right 
>> place. (Also, Ryan, if you think our goals are more similar than I do, I'd 
>> be happ

[racket-users] SQL DB tooling

2019-03-22 Thread Aidan Gauland
I see that Racket has a couple of nice libraries for talking to SQL
databases  and
, but I have been unable to find any
equivalent to the so-called "migrations" capability of DB libraries from
other languages (see
 and
  for examples).  Is there
anything like this for Racket, or even some language-agnostic, CLI tool
that does the same thing?

Thanks,
Aidan Gauland

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.