Libuv wrappers for PureC (WIP)

purec

#1

Hey, I’ve started to put together a experimental project over the last couple of days, effectively wrapping libuv using PureC. Imagine compiling from PureScript straight down to C and then hooking into libuv directly, side-stepping node.js entirely. It might seem insane at first to even attempt such a project, but so far I have not been disappointed. As it turns out most of the code in the node.js codebase I have seen so far is essentially concerned about integrating with JavaScript and making things usable in an OOP setting.

Example:

testUdp :: _ -> UV.Handler _ Unit
testUdp loop = do
  recvH <- UV.udpNew loop
  UV.udpBind (UV.ip4Addr "0.0.0.0" 1234) [ UV._UdpReuseAddr ] recvH
  UV.udpRecvStart <@> recvH $ \(mBuf :: Maybe UV.Buffer) -> do
    mS <- traverse UV.bufferToString mBuf
    Console.log $ "udp: received: " <> show mS
  sendH <- UV.udpNew loop
  buf <- lift $ UV.bufferFromString "hello"
  UV.udpSend [ buf ] (UV.ip4Addr "0.0.0.0" 1234)
    (case _ of
      Right _ ->
        Console.log "udp: sent"
      Left errCode ->
        Console.log $ renderErrCode errCode
    ) sendH

The API is purposely low-level, and once complete could be wrapped up into something nice to use. Like a purescript-aff for PureC using libuvs async primitives.

The project lives here for now: https://github.com/pure-c/purec-uv. Don’t bother trying to compile and run it yet, though - I need to clean up a little first when I get around to it. Just wanted to post this here, gather feedback, and maybe find people interested in building this thing out.


#2

Does it mean that PureC is possibly one or two steps (maybe not so small) from Aff?

P.S.
Where can I find funding channel for Pure-C project @felixschl? :stuck_out_tongue:


#3

This is incredibly cool! :heart_eyes:


#4

Once I wrap up the async stuff I’ll have a better idea but i think it should translate nicely into some platform specific lose equivalent. Should be fun to explore this


#5

I second the funding part. purescript-express running natively without node.js middleman!


#6

I am open to it, and keen to build this out. I am sure being able to place bounties/rewards or whatever on tasks would attract potential contributors as well. Do you guys have any ideas on how to set this up?


#7

I’ve seen github issues that link directly to bountysource, like here: https://github.com/elementary/appcenter/issues/859


#8

That’s even better than what I had in mind!


#9

@thimoteus @felixschl
Yeah, bountysource seems to be even better than any other channel. I have to rethink what interest me most and I would open something (maybe not huge starting as my personal bounty) project soon!


#10

Update: I’ve started porting purescript-aff to C and then added an Aff wrapper for the UV stuff. That’s what testUdp looks like now:

  where
  testUdp :: UV.Loop -> UV.Handler _ Unit
  testUdp loop = do
    recvH <- UV.udpNew loop
    UV.udpBind (UV.ip4Addr "0.0.0.0" 1234) [ UV._UdpReuseAddr ] recvH
    UV.udpRecvStart <@> recvH $ \mBuf -> do
      mS <- traverse UV.Buffer.toString mBuf
      Console.log $ "udp: received: " <> show mS
    sendH <- UV.udpNew loop
    buf   <- liftEffect $ UV.Buffer.fromString "udp: hello"
    UV.udpSend [ buf ] (UV.ip4Addr "0.0.0.0" 1234) sendH

#11

This is just crazy stuff. Not much to add technically – just keep it up! I’m excited by all these updates!


#12

Thank you for the kind words - I think I am onto something which is why I keep chipping away at this, but it’s just so much work. Seeing interest expressed like this gives me more motivation to see it through and keep believing in the value of it. Not sure where to take this project next to have it reviewed (pure-c in general) and find a community to develop this further. Otherwise the project fill eventually fizz out and starve from lack of interest - fingers crossed that won’t happen. I need to do some research how similar projects started pulling wider interest.


#13

One valuable approach might be selecting some problem / task that PureC can solve in a nicer, less error-prone, faster, etc. way than the typical way to solve that problem.

From the README and examples I’m able to see that this works but it’s a little difficult to conceptualize what to use it for. Is it meant to be a replacement for when you would otherwise write C? Or to replace writing applications that might otherwise run on Node? A way to get to WebAssembly via C?

If one of those has a standout “There’s no really good way to do X right now,” and it can be done with PureC, then that would be a great way to test out the implementation and publish the results to get some attention and get other folks thinking about other problems they might want to solve with this.

It can be hard to bridge the gap between “This is fascinating!” and “Shit, I want to use that!” and while the first is valuable I think the second will give you more of that persistent community.