mdconn_uk
2021-3-19 11:03:54

@mdconn_uk has joined the channel


chansey97
2021-3-19 15:17:15

Does Racket support annotation mechanism (like Java or C# annotation)? Programmers can tag some annotation in program and read them via reflection.


samth
2021-3-19 15:19:03

No, there is not a built-in annotation mechanism. You can use some things to do similar stuff (like chaperone properties) but that would require manual work.


chansey97
2021-3-19 15:24:34

Thanks. I am thinking about how to implement DI container in Racket. For example, in Java or C#, annotation mechanism be used to implement DI container.


chansey97
2021-3-19 15:25:10

Is DI container useful in Racket?


samth
2021-3-19 15:25:45

People do not do a lot of DI in Racket.


samth
2021-3-19 15:26:00

Maybe that’s just preference, or what kinds of programs people build.


samth
2021-3-19 15:26:54

If you did do DI, I think the most likely ways would be 1. macros for defining code that took dependencies as arguments 2. using units 3. just using plain old functions


hectometrocuadrado
2021-3-19 15:29:41

Using Scribble I got this: WARNING: no declared exporting libraries for definition in: function-name


hectometrocuadrado
2021-3-19 15:30:10

What does that means?


hectometrocuadrado
2021-3-19 15:30:18

How can I fix that?


samth
2021-3-19 15:32:05

@hectometrocuadrado probably you need a @defmodule for the library you’re documenting


hectometrocuadrado
2021-3-19 15:37:05

Something like @defmodule["file.rkt"] ?


chansey97
2021-3-19 15:37:13

One advantage of the DI container is that it can construct an object graph automatically instead of manually. This is very convenient to construct deeply nested components which depend on shared components. The unit system in Racket is a bit like Poorman injection.

Of course, I’m just thinking. At present I have not encountered such a complicated use case in Racket.


sorawee
2021-3-19 15:37:49

@defmodule[mixfix]


sorawee
2021-3-19 15:38:01

where mixfix is your module


sorawee
2021-3-19 15:40:22

Btw, you might want to use raco pkg new when you start a new project.


hectometrocuadrado
2021-3-19 15:40:25

Has the module to be a path?


sorawee
2021-3-19 15:40:31

It will generate a Scribble file for you automatically


hectometrocuadrado
2021-3-19 15:41:16

I created the scribble file in a different directory


sorawee
2021-3-19 15:41:32

I’m not sure what you mean by that. In my mixfix package, users would write (require mixfix), so mixfix is the path to my module.


sorawee
2021-3-19 15:42:02

It doesn’t matter where your Scribble file is.


hectometrocuadrado
2021-3-19 15:42:49

I think I’m missing something


hectometrocuadrado
2021-3-19 15:42:50

xd


sorawee
2021-3-19 15:43:37

Are you creating a package?


hectometrocuadrado
2021-3-19 15:44:36

Nope. Just a bunch of rkt files for my own use.


hectometrocuadrado
2021-3-19 15:45:50

I wanted to make a scribble manual to have a site where I could see how the functoons are.


hectometrocuadrado
2021-3-19 15:46:22

Also, I wanted to practice with scribble


sorawee
2021-3-19 15:46:24

I guess a short answer is that, it’s kinda tricky to write a Scribble without installing the code that you are documenting as a package. It might be possible to do so, but I tried it before and failed.


sorawee
2021-3-19 15:46:51

So if you can install it as a package, that would simplify things


hectometrocuadrado
2021-3-19 15:47:10

So, the easy way is documenting a package


sorawee
2021-3-19 15:47:11

Note that you don’t need to upload the package to the package server. You can just have a local package


hectometrocuadrado
2021-3-19 15:47:28

I see. Thanks!


greg
2021-3-19 15:54:13

Although I might be misunderstanding, I think another way is:

  1. Parameters. As in make-parameter to define them, and parameterize to set values for some dynamic extent.

greg
2021-3-19 15:54:29

By convention these are often named current-x. current-output-port, current-eval, current-pretty-print-width, etc.


greg
2021-3-19 15:54:42

In some sense this is like 1, but without the explicit extra function parameters.


chansey97
2021-3-19 16:10:53

@greg Dynamic scoping as dependency injection is a good idea. What surprised me is that there is very few people mention this idiom in programming community.


greg
2021-3-19 16:15:49

That might be because hardly anyone using Racket is doing so-called “enterprise” development? (That’s just my own impression/guess. Both about the Racket community. And also that DI is mainly used in “enterprise” development teams.)


samth
2021-3-19 16:16:26

Can one of you explain what people actually use DI for?


greg
2021-3-19 16:16:36

Not really. :slightly_smiling_face:


greg
2021-3-19 16:17:35

Probably @chansey97 can. I’ve only seen e.g. “Spring” used in a Java app. In my personal opinion it made the app deeply difficult to understand, from looking at the source code. (to be fair, you could say the same about “excessively macro-ized” code.)


samth
2021-3-19 16:18:41

But what problem were they trying to solve?


samth
2021-3-19 16:18:55

Even if spring/DI wasn’t a good solution


greg
2021-3-19 16:19:00

I have a little more mileage with so-called “12 Factor Apps” stuff in the web dev community. That mainly says, use env vars for config.


greg
2021-3-19 16:20:00

In the specific case I saw, the honest answer? The person was trying to use enterprise dev best practices, and everyone uses Spring (they felt), so they ought to, also.


greg
2021-3-19 16:20:17

I had similar questions as you and never got a satisfying answer.


greg
2021-3-19 16:21:10

But that’s just my one data point. I’m not trying to pee all over DI and say it’s never useful. I just don’t have a compelling example motivation to offer. Consider that a limitation of me, not DI.


greg
2021-3-19 16:23:07

In my own data point: The company was delivering a Java app that customers would install on their JVM app servers. They wanted the app to work with whatever the company used for database, messaging queues, and stuff like that. So it was an end-user configuration problem — that was the motivation.


greg
2021-3-19 16:23:30

I just don’t have a great pitch for why DI needed to be the solution.


greg
2021-3-19 16:24:04

To be fair, “that’s what enterprise customers expect” could be a 100% valid answer from a business POV.


samth
2021-3-19 16:24:08

So lots of things needed to be parameterized over some choices (like the database) and DI was the parameterization mechanism chosen.


greg
2021-3-19 16:25:13

Yes. Although in the case I saw, it wasn’t that many choices or that many things that needed to be parameterized. So it felt like overkill. Sort of “for the future”, “wishful planning ahead”.


samth
2021-3-19 16:26:06

In Java presumably the fact that you can’t just wrap your class in a lambda makes a difference


greg
2021-3-19 16:28:28

Yes. And even if you could do it that way, I don’t know if people would do it that way. I think there’s a “culture” difference. (You can chicken-and-egg which caused which, I suppose.)


greg
2021-3-19 16:29:29

A fair chunk of enterprise dev teams are kind of like visiting a Plimoth Plantation for 90s programming ideas. :slightly_smiling_face:


chansey97
2021-3-19 16:34:10

I think we should distinguish between DI and DI container. IMO, DI is a very commonly used design pattern, such as SML functor, Scala Cake pattern, or Racket unit, etc. In the DI scenario, we usually have a composition root, where we assemble the entire program.


chansey97
2021-3-19 16:36:01

The DI container just makes the assembly process easier.


chansey97
2021-3-19 16:52:29

Look this example: public class Service { @Inject private Logger logger; @Inject private Processor processor; public void execute(String command) { logger.log("executing " + command); processor.process(command); logger.log("executed " + command); } } public class ProcessorImpl implements Processor { @Inject private Logger logger; public void process(Object o) { logger.log("processing"); System.out.println("processing " + o + "..."); } } public class StandardModule extends AbstractModule { @Override protected void configure() { bind(Processor.class).to(ProcessorImpl.class); } } Injector injector = Guice.createInjector(new StandardModule()); Service service = injector.getInstance(Service.class);


chansey97
2021-3-19 16:54:29

Here Service depends on Logger and Processor, a ProcessorImpl depends on Logger. Note that in this example in fact we created two loggers, but you can make logger sharing as well.


chansey97
2021-3-19 17:08:00

Another complicated example is xText. I once used xText to create DSL in Java. They used DI container very frequently.

xText provides a compiler framework: You just fill code in the framework without knowing the entire architecture (which deep integrates with Eclipse IDE). So you need DI container to embed your own components.


samth
2021-3-19 17:19:28

I think I’d use parameters for that example in Racket


chansey97
2021-3-19 17:21:03

I agree.


chansey97
2021-3-19 17:23:35

DI container is just one application of annotation. The annotation mechanism seems powerful.


samdphillips
2021-3-19 19:58:27

@popa.bogdanp has a package that let’s you do a kind of DI. I’ve not used it myself. https://docs.racket-lang.org/component/index.html


juanesgonzalez746
2021-3-19 21:39:28

How can I make a Cartesian plane in scheme?


kellysmith12.21
2021-3-19 21:50:06

Could you please elaborate on what you’re trying to do? Do you want to plot a plane, do simple operations on points…?


juanesgonzalez746
2021-3-19 22:05:47

I need to make a Cartesian plane and locate three points on this


badkins
2021-3-19 22:14:54

{ (0,0), (1,0), (0, 1) }


badkins
2021-3-19 22:16:16

I suppose to Racket-ify it: (define plane '((0 . 0) (0 . 1) (1 . 0)))


juanesgonzalez746
2021-3-19 22:23:31

but I have to create the plane using canvas and then locate the points in this


notjack
2021-3-19 23:04:16

What Racket uses parameters for is 100% the exact kind of thing that Java uses DI for


notjack
2021-3-19 23:05:04

(for context: a lot of my day job involves DI-heavy Java)


notjack
2021-3-19 23:06:38

There’s some differences in the approach but by and large they’re tackling the same problem: how to make certain parts of code dynamically configurable without making more work for callers (as adding function parameters or wrapping things in lambdas or units would do, those all affect callers heavily)


samdphillips
2021-3-19 23:06:40

This is pure perception: it seems that Java objects via DI are a bit more complicated than the objects that get used through parameters. Not that more complicated things cannot be used with parameters.


notjack
2021-3-19 23:08:00

There’s more that’s possible. But it’s not much more complex than what people sometimes do with parameters, where they set up multiple parameters whose current values are dependent on other parameters.