Zulip Chat Archive
Stream: lean4
Topic: http requests
Adam Topaz (Feb 08 2023 at 00:06):
What's the state of the art for making http(s) requests using lean4? I remember that someone was working on an http library a while ago, but I can't seem to find it. Is this the best approach? If I understand correctly, lake has some wrappers around curl for such requests, is that right?
Matthew Ballard (Feb 08 2023 at 00:08):
https://github.com/xubaiw/Socket.lean/tree/main/examples/http-server ?
Adam Topaz (Feb 08 2023 at 00:11):
yeah I think that's the repo I was thinking of. Thanks. I guess what I'm looking for is something with a similar functionality as python's requests package.
Adam Topaz (Feb 08 2023 at 00:11):
I suppose such a thing doesn't exist.
Henrik Böving (Feb 08 2023 at 07:06):
Such a thing does indeed not exist yet.
Joachim Breitner (Aug 17 2023 at 16:18):
The repo you linked above archived now. Are there “serious” lean4 libraries for Sockets/TCP/HTTP already?
François G. Dorais (Aug 17 2023 at 16:33):
Not that I know of but this is something I seriously considered doing, I gave up thinking that somebody with better knowledge than me would eventually do it. I'm still very interested though!
Henrik Böving (Aug 17 2023 at 16:33):
The above is the only one that I am aware of. And getting this done in an async fashion is even further out of reach right now.
Henrik Böving (Aug 17 2023 at 16:48):
That said my reason for not doing it is the same as @François G. Dorais so maybe someone :tm: should just do it :D
Adam Topaz (Aug 17 2023 at 23:30):
Presumably it should be relatively easy to make a wrapper around the curl c api
Adam Topaz (Aug 17 2023 at 23:31):
Anyway, it would be great to have such a thing.
Pim Otte (Aug 18 2023 at 04:51):
As far as I know, https://github.com/lurk-lab/Http.lean is state of the art (and building on a fork of repo archived above)
Henrik Böving (Aug 19 2023 at 21:10):
Henrik Böving said:
That said my reason for not doing it is the same as François G. Dorais so maybe someone :tm: should just do it :D
I'll do it to learn alloy now^^
Arthur Paulino (Aug 19 2023 at 21:50):
Developing a proper HTTP request API for Lean 4 is definitely something I've wanted to do for a while. If someone is going to spearhead such a project and needs an extra pair of hands, just ping me or send a DM
Henrik Böving (Aug 19 2023 at 22:21):
@Mac Malone i've got this setup so far: https://github.com/hargoniX/socket.lean and I tried to compile just to see if it works and am getting
ld.lld: error: relocation R_X86_64_32S cannot be used against local symbol; recompile with -fPIC
>>> defined in ./build/ir/Socket.alloy.c.o
>>> referenced by Socket.alloy.c
>>> ./build/ir/Socket.alloy.c.o:(lean_mk_socket)
ld.lld: error: relocation R_X86_64_32S cannot be used against local symbol; recompile with -fPIC
>>> defined in ./build/ir/Socket.alloy.c.o
>>> referenced by Socket.alloy.c
>>> ./build/ir/Socket.alloy.c.o:(lean_mk_socket)
ld.lld: error: relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC
>>> defined in ./build/ir/Socket.alloy.c.o
>>> referenced by Socket.alloy.c
>>> ./build/ir/Socket.alloy.c.o:(lean_mk_socket)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: external command `/home/nix/.elan/toolchains/leanprover--lean4---nightly-2023-08-19/bin/leanc` exited with code 1
any idea? do I have to sneak -fPIC in?
Mac Malone (Aug 19 2023 at 22:23):
@Henrik Böving I would certainly give-fPIC
a try (via moreLeancArgs
).
Henrik Böving (Aug 19 2023 at 22:24):
That seems to work indeed
Henrik Böving (Aug 19 2023 at 22:24):
Can a linker magician tell me why I need FPIC? :D
Mac Malone (Aug 19 2023 at 22:27):
@Henrik Böving It sounds like it may be due to mixing shared and static libraries based on this StackOverflow question.
Mac Malone (Aug 19 2023 at 22:28):
However, I am curious why I never encountered this problem in the Alloy S test.
Mac Malone (Aug 19 2023 at 22:31):
@Henrik Böving A more generally comment on your code. One of the advantages of Alloy is that C code is now Lean code, so you can use Lean metaprogramming to generate definitions. For instance, you could define some custom syntax/elaborator to map your enums to C and back instead of having to write it all manually.
Henrik Böving (Aug 19 2023 at 22:32):
Oh :eyes: that's a good idea yeah, i'll try that
Mac Malone (Aug 19 2023 at 22:37):
@Henrik Böving Also, if anything breaks, report it! I have only tested Alloy on a few examples, so you are essentially an Alloy beta tester. Thus, I would appreciate any feedback you can provide (both bugs and feature requests). Also, do not be hesitant to blame any breakage on Alloy. :laughing:
Henrik Böving (Aug 19 2023 at 22:38):
:D sure!
Henrik Böving (Aug 19 2023 at 23:07):
@Mac Malone I have one right away!
`(command|
alloy c section
static inline $cType $leanToC($ffiType arg) {
}
end
)
where
ffiType : Ident
application type mismatch
ffiType.raw
argument
ffiType
has type
Ident : Type
but is expected to have type
TSyntax `Alloy.C.pointer : Type
is there a nice way to make these or do I go the raw route?
Mac Malone (Aug 19 2023 at 23:11):
@Henrik Böving Could you give a full #mwe? (i.e., with an example of what cType
and leanToC
are as well)
Henrik Böving (Aug 19 2023 at 23:11):
syntax "alloy" "c" "enum" ident " : " ident "translators" ident " ↔ " ident "where" ("| " ident " = " ident)+ : command
macro_rules
| `(command| alloy c enum $name:ident : $cType:ident translators $leanToC:ident ↔ $cToLean:ident where $[| $leanVariant:ident = $cVariant:ident]*) => do
let ffiType ←
if leanVariant.size <= 2^8 then
pure <| mkIdent `uint8_t
else if leanVariant.size <= 2^16 then
pure <| mkIdent `uint16_t
else if leanVariant.size <= 2^32 then
pure <| mkIdent `uint32_t
else
Macro.throwError s!"Enum {name} has more than 2^32 variants, this is not supported"
`(command|
alloy c section
static inline $cType $leanToC($ffiType arg) {
}
end
)
Mac Malone (Aug 19 2023 at 23:22):
@Henrik Böving It is clear I am missing some TSyntax
Coe
instance, the question is: which ones/ Currently working on it.
Henrik Böving (Aug 19 2023 at 23:22):
I'll use the fast forward button (formely known as "sleeping") in that case :P
Mac Malone (Aug 19 2023 at 23:31):
@Henrik Böving Having finished investigating, this is actually just due to ambiguities of the C grammar. You just need to be explicit about the syntax kind:
static inline $cType $leanToC:ident($ffiType:ident arg) {}
Mac Malone (Aug 20 2023 at 01:53):
Also, out of curiosity, @Henrik Böving, are you making use of Alloy's clangd
LSP integration (i.e., do you see semantic highlighting, hovers, go-to-def, etc. in C code)?
Joachim Breitner (Aug 20 2023 at 08:36):
After seeing your message I tried it in loogle (by changing the nix shell to use the clang-stdenv, so any problems may be nix-related), but I get
Lean (version 4.0.0-nightly-2023-08-15, commit b5a736708f40, Release)
E[10:35:06.889] Trying to remove file from TUScheduler that is not tracked: /dev/null
[Error - 10:35:06] Request textDocument/semanticTokens/range failed.
Message: C language server request 3 failed: trying to get AST for non-added document
Code: -32602
Henrik Böving (Aug 20 2023 at 09:00):
Mac Malone said:
Also, out of curiosity, Henrik Böving, are you making use of Alloy's
clangd
LSP integration (i.e., do you see semantic highlighting, hovers, go-to-def, etc. in C code)?
I do see proper highlighting of the code yes, didn't try the rest yet
Henrik Böving (Aug 20 2023 at 10:02):
I present the final:
macro_rules
| `(command| alloy c enum $name:ident : $cType:ident translators $leanToC:ident ↔ $cToLean:ident where $[| $leanVariant:ident = $cVariant:ident]*) => do
let ffiType ←
if leanVariant.size <= 2^8 then
pure <| mkIdent `uint8_t
else if leanVariant.size <= 2^16 then
pure <| mkIdent `uint16_t
else if leanVariant.size <= 2^32 then
pure <| mkIdent `uint32_t
else
Macro.throwError s!"Enum {name} has more than 2^32 variants, this is not supported"
let counter := Array.range leanVariant.size |>.map (Syntax.mkNumLit <| toString ·)
`(
inductive $name : Type where $[ | $leanVariant:ident]*
alloy c section
static inline $cType $leanToC:ident($ffiType:ident arg) {
switch (arg) {
$[
case $counter:num:
return $cVariant:ident;
]*
default:
lean_panic_fn(lean_box(-1), lean_mk_string("illegal C value"));
}
}
static inline $ffiType $cToLean:ident($cType:ident arg) {
switch (arg) {
$[
case $cVariant:ident:
return $counter:num;
]*
default:
lean_panic_fn(lean_box(-1), lean_mk_string("illegal Lean value"));
}
}
end
)
Sadly all of those annotations are necessary right now. But I'm quite happy it just seems to work out! The highlighting also works very nicely!
Mac Malone (Aug 20 2023 at 11:30):
@Henrik Böving I added a many more coercions last night and one more right now which allowed me to get it down to this:
case $counter:constExpr:
return $cVariant;
[...]
case $cVariant:constExpr:
return $counter;
But sadly many of those annotations don't seem removable.
Henrik Böving (Aug 20 2023 at 11:36):
That's fine for me right now, If you know about it it becomes trivial^^
I do have a second idea already as well, for the sockaddr_in and sockaddr_in6 i essentially just need to manage a void pointer with Lean so I wrote this:
scoped syntax "alloy" "c" "alloc" ident " = " ident "as" ident "translators" ident " ↔ " ident "finalize" ident : command
macro_rules
| `(command| alloy c alloc $name:ident = $cName:ident as $externClass:ident translators $leanToC:ident ↔ $cToLean:ident finalize $finalizer:ident) =>
let nonemptyType := mkIdent <| name.getId.append `nonemptyType
`(
opaque $nonemptyType : NonemptyType
def $name : Type := NonemptyType.type $nonemptyType
instance : Nonempty $name := Subtype.property $nonemptyType
alloy c section
static lean_external_class* $externClass:ident = NULL;
static void $finalizer:ident(void* ptr) {
free(($cName:ident*)ptr);
}
static inline lean_object* $cToLean:ident($cName:ident* ptr) {
if ($externClass:ident == NULL) {
$externClass:ident = lean_register_external_class($finalizer:ident, NULL);
}
return lean_alloc_external($externClass:ident, ptr);
}
static inline $cName:ident* $leanToC:ident(b_lean_obj_arg ptr) {
return ($cName:ident*)(lean_get_external_data(ptr));
}
end
)
used like so
alloy c alloc SockAddr4 = sockaddr_in as g_sockaddr_in_external_class translators sockaddr_in_to_lean ↔ lean_to_sockaddr_in finalize sockaddr_in_finalize
which gives me the new and exciting!
command is ill-formed (cannot be reprinted)
how do I go from here? :D
Mac Malone (Aug 20 2023 at 11:46):
@Henrik Böving To fix it, use $cToLean:ident($cName* ptr)
instead of $cToLean:ident($cName:ident* ptr)
. Why this is happening I am not quite sure.
Mac Malone (Aug 20 2023 at 11:47):
Somehow the annotation is producing some syntax it cannot reprint.
Henrik Böving (Aug 20 2023 at 11:53):
That works indeed, next question! Since sockaddr_in
is a struct
that is not typedef-ed I need to struct sockaddr_in
in my generated C code. What is the proper category to replace ident
on the cName
variable with? @Mac Malone
Mac Malone (Aug 20 2023 at 11:54):
@Henrik Böving If you update, it should figure that one out automatically (I tested that so it should hopefully work).
Mac Malone (Aug 20 2023 at 11:55):
(For reference though, the kind is aggrSig
.)
Henrik Böving (Aug 20 2023 at 11:55):
Is it not cTypeSpec?
Mac Malone (Aug 20 2023 at 11:56):
Oh, maybe I am misunderstanding. What do you want to exactly?
Mac Malone (Aug 20 2023 at 11:56):
I thought you just wanted to do struct $var:kind
Henrik Böving (Aug 20 2023 at 11:57):
Ah that is also an option yes. But I was thinking about keeping it generic maybe? So turning:
scoped syntax "alloy" "c" "enum" ident " : " ident "translators" ident " ↔ " ident "where" ("| " ident " = " ident)+ : command
into a syntax that accepts (syntactically) both:
alloy c alloc SockAddr4 = sockaddr_in as struct g_sockaddr_in_external_class translators sockaddr_in_to_lean ↔ lean_to_sockaddr_in finalize sockaddr_in_finalize
and
alloy c alloc SockAddr4 = sockaddr_in as g_sockaddr_in_external_class translators sockaddr_in_to_lean ↔ lean_to_sockaddr_in finalize sockaddr_in_finalize
such that a user is not necessarily forced to use it with structs
Henrik Böving (Aug 20 2023 at 11:58):
So my question is what do I have to replace the second ident
in the syntax
decl with such that it captures struct sockaddr_in
and also just a basic sockaddr_in
? Or in general any valid c type I guess.
Mac Malone (Aug 20 2023 at 12:01):
Oh, that is actually a bit complicated depending on the generality you are going for. The C grammar is weird.
Henrik Böving (Aug 20 2023 at 12:02):
:sad: maybe just struct ident
and ident
then? :D Do we have something for that?
Mac Malone (Aug 20 2023 at 12:02):
However, I think in your case what you want is cDeclSpec+
.
Henrik Böving (Aug 20 2023 at 12:03):
O_o why the +
?
Mac Malone (Aug 20 2023 at 12:03):
What makes it interesting is you then want to to put a pointer after it, which happens to be be the convenient boundary point.
Mac Malone (Aug 20 2023 at 12:06):
Henrik Böving said:
O_o why the
+
?
Because your presumable also want to accept thins like const struct sockaddr_in
.
Mac Malone (Aug 20 2023 at 12:07):
however, if you do just want plain types, you are correct that the category iscTypeSpec
.
Henrik Böving (Aug 20 2023 at 12:08):
Hurray it works indeed. This is the most fun i've had with C in a while :D
Mac Malone (Aug 20 2023 at 12:09):
@Henrik Böving It is worth noting that this will not accept a pointer type like char*
for instance.
Henrik Böving (Aug 20 2023 at 12:09):
I hope that I won't want to box pointers for now :D
Mac Malone (Aug 20 2023 at 12:11):
@Henrik Böving Well, with that done, I will myself be heading to sleep myself (that is time zone differences for you).
Mac Malone (Aug 20 2023 at 12:12):
Happy I was able to help you have some fun with C!
Mac Malone (Aug 20 2023 at 12:20):
@Henrik Böving One final note: For lean_register_external_class
, I was under the impression you had to provide handler for both (i.e., NULL
was not a valid option). If you want it to be a no-op, you needed to define a no-op handler.
Henrik Böving (Aug 20 2023 at 12:38):
I might have found a bug in your grammar now^^
def IPv4Addr := UInt32
def IPv4Addr.mk (first second third fourth : UInt8) : IPv4Addr :=
first.toUInt32 <<< 24 ||| second.toUInt32 <<< 16 ||| third.toUInt32 <<< 8 ||| fourth.toUInt32
alloy c extern "lean_mk_sockaddr_in"
def SockAddr4.mk (ip : IPv4Addr) (port : UInt16) : Unit := {
struct sockaddr_in* sa = malloc(sizeof(struct sockaddr_in));
.......
}
This fails to parse but if I turn the malloc
into: malloc(sizeof(sockaddr_in))
it parses although now the c compiler is of course very unhappy. I'll work around it with a typedef for now.
Henrik Böving (Aug 20 2023 at 15:34):
image.png
:sparkles:
Sebastian Ullrich (Aug 20 2023 at 16:09):
This is a nice thread, it's great to see what is already possible. We should also document what is missing in the FFI to make this feasible purely in Lean.
Henrik Böving (Aug 20 2023 at 16:18):
To make what exactly feasible purely in Lean? @Sebastian Ullrich Do you want to get to the point where we don't have to write C at all?
Sebastian Ullrich (Aug 20 2023 at 16:20):
Yes, that's what I would expect from a complete FFI, no?
Henrik Böving (Aug 20 2023 at 16:22):
Hm, not really no. For example in OCaml it is very common to write C code still. They also have absolutely awesome docs on their FFI: https://v2.ocaml.org/manual/intfc.html I think if we can get to the level of this document we should be fine for a while^^
Sebastian Ullrich (Aug 20 2023 at 16:36):
So OCaml supports only homogeneous value
FFI signatures? We are already beyond that, and I see no reason not to move even further.
Henrik Böving (Aug 20 2023 at 16:45):
No, they do also have unboxed values (namely everything <= 63 bit can be unboxed, 63 because the 64th bit is used for the box/unbox tag) and external allocations just like we do. They also have a bunch of special stuff like float arrays without indirection just like we do. In general I feel like modulo the garbage collector vs RC stuff our FFI is actually not that different from OCaml.
And on top of that they have Eisenberg (the GHC Eisenberg) working on more unboxed stuff at JaneStreet so I would expect something to come out of that in the not too distant future as well.
Sebastian Ullrich (Aug 20 2023 at 16:50):
User primitives with arity n ≤ 5 are implemented by C functions that take n arguments of type value, and return a result of type value
This seems quite clear to me. In any case, OCaml appears to be a relative outlier here, I can't think of any other compiled language that wants you to write C code for interfacing (of course, OCaml is not exclusively compiled, which might be one reason for this design).
MangoIV (Aug 20 2023 at 16:58):
You will find many libraries in the Haskell ecosystem that uses generated c compatibility shims e g https://github.com/haskell/hsc2hs generates c code, too
Henrik Böving (Aug 20 2023 at 16:58):
Which languages are you thinking about here? The ones that come to mind for me instantly would be C, C++, Rust, Golang and Haskell.
C/C++ are obviously not relevant here.
With Rust you can do everything in Rust indeed but they also have support for C constructs that we don't afaik?:
- directly integrated pointers
- unions
- the
#[repr(C)]
- on top of that you usually use an FFI generator but that's more of a bonus.
Golang has cgo
which is effectively an FFI generator that spits out both golang and C files as well.
For haskell I don't quite know what they do
Mac Malone (Aug 20 2023 at 20:45):
Sebastian Ullrich said:
Yes, that's what I would expect from a complete FFI, no?
While a great feature, having it would be surprising. Rust is the only language I know of that has something close to this and that is because it supports exact C calling conventions and data representations (so you do essentially write C in Rust). Every other major language language I know of, both compiled and interpreted, use C shims to fill in gaps in the FFI: Haskell, Java, PHP, Python, Ruby, JavaScript, , etc.
Mac Malone (Aug 20 2023 at 21:04):
Henrik Böving said:
I might have found a bug in your grammar now^^
Fixed. This grammar mistake was a result of me misreading a formatting error in Microsoft's C Language Syntax Summary. Its grammar for the type-based sizeof
is written as follows:
unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name ) _Alignof ( type-name )
Where the final sizeof
and _Alignof
should be on separate lines.
Henrik Böving (Aug 22 2023 at 17:58):
I have new cursed stuff for you! @Mac Malone The manpages for unix domain sockets demonstrate this syntax:
strncpy(sa->sun_path, lean_string_cstr(path), sizeof(sa->sun_path) - 1);
like so for example:
alloy c extern "lean_mk_sockaddr_un"
def SockAddrUnix.unix (path : @& System.FilePath) : SockAddrUnix := {
struct sockaddr_un* sa = malloc(sizeof(struct sockaddr_un));
sa->sun_family = AF_UNIX;
strncpy(sa->sun_path, lean_string_cstr(path), sizeof(sa->sun_path) - 1);
return sockaddr_un_to_lean(sa);
}
your sizeof grammar does not approve
Richard Copley (Aug 22 2023 at 18:20):
What goes wrong? (sa->sun_path)
is a fine unary-expression
, and (sa->sun_path) - 1
is not; and sa->sun_path
isn't a type-name
. (However, strncpy
is cursed.)
Henrik Böving (Aug 22 2023 at 18:24):
It complains at the -
of the ->sun_path
that it expects a )
Henrik Böving (Aug 22 2023 at 18:25):
It being alloy, so the grammar implemented in alloy still seems to be flawed
Mac Malone (Aug 22 2023 at 18:41):
@Henrik Böving Fixed. My implementation was missing an atomic
.
Henrik Böving (Aug 22 2023 at 18:49):
Yay that works
Henrik Böving (Aug 22 2023 at 20:08):
Okay I think I got a basic socket API for UNIX based systems working and documented now. Next thing would of course be :window: @Mac Malone do you have a particular story for cross platform in mind with alloy? Or is it also intended as an ifdef macro massacre?
Mac Malone (Aug 22 2023 at 20:10):
@Henrik Böving ifdef
is how it is done in core, so at least for now, that is how I would assume FFIs would do it.
Henrik Böving (Aug 22 2023 at 20:12):
Okay. But #ifdef
doesn't seem to work with alloy code blocks (probably given that it is not valid C but preprocessor C?) so what is the intended integration way here?
Henrik Böving (Aug 22 2023 at 20:14):
In particular also with #include
's given that I need to work with the win32 header files to get sockets going properly.
Mario Carneiro (Aug 22 2023 at 20:15):
the lean 4 equivalent of #ifdef
is meta if
, not sure if it is applicable here
Mac Malone (Aug 22 2023 at 20:30):
Henrik Böving said:
Okay. But
#ifdef
doesn't seem to work with alloy code blocks (probably given that it is not valid C but preprocessor C?) so what is the intended integration way here?
It should work. #ifdef
is part of the Alloy's C grammar. Do you have an example breakage?
Henrik Böving (Aug 22 2023 at 20:31):
Mac Malone said:
Henrik Böving said:
Okay. But
#ifdef
doesn't seem to work with alloy code blocks (probably given that it is not valid C but preprocessor C?) so what is the intended integration way here?It should work.
#ifdef
is part of the Alloy's C grammar. Do you have an example breakage?
alloy c extern "lean_mk_socket"
def mk (family : @& AddressFamily) (type : @& Typ) : IO Socket := {
int af = lean_to_socket_af(family);
int typ = lean_to_socket_type(type);
#ifdef FOO
int* fd = malloc(sizeof(int));
#endif
*fd = socket(af, typ, 0);
if (*fd < 0) {
free(fd);
return lean_io_result_mk_error(lean_decode_io_error(errno, NULL));
} else {
return lean_io_result_mk_ok(socket_to_lean(fd));
}
}
Mac Malone (Aug 22 2023 at 20:33):
Oh, yeah, I made pp directives just commands, not statements. Need to fix that.
Mac Malone (Aug 22 2023 at 20:55):
@Henrik Böving Examples like yours should now work.
Henrik Böving (Aug 22 2023 at 20:55):
Nice. What about the include
lines? Do I meta if
those?
Mac Malone (Aug 22 2023 at 20:56):
@Henrik Böving No, this should work:
alloy c section
#ifdef WIN32
#include <windows/windows.h>
#else
#include <unistd.h>
#endif
end
Henrik Böving (Aug 22 2023 at 20:57):
Ah of course^^
Henrik Böving (Aug 22 2023 at 23:03):
@Mac Malone do we have a story for injecting linker arguments to leanc based on platform or is this a meta if job? It's because I gotta -lws2_32
but of course only on windows
Mac Malone (Aug 22 2023 at 23:04):
@Henrik Böving You can just us normal Lean syntax for that (i.e., if Platform.isWindows then ... else ...
)
Henrik Böving (Aug 22 2023 at 23:21):
Mac Malone said:
Henrik Böving You can just us normal Lean syntax for that (i.e.,
if Platform.isWindows then ... else ...
)
I got this now: https://github.com/hargoniX/socket.lean/blob/main/lakefile.lean#L14 but the flag is not properly injected into the leanc call that is used to build the alloy shim:
[89/95] Compiling Socket
[89/95] Generating Socket alloy
[90/95] Compiling Socket alloy
error: > c:\Users\runneradmin\.elan\toolchains\leanprover--lean4---nightly-2023-08-19\bin\leanc.exe -shared -o .\build\lib\Socket-1.dll .\build\ir\Socket.o .\build\ir\Socket.alloy.c.o -L.\lake-packages\alloy\build\lib -L.\lake-packages\std\build\lib -L.\build\lib -lAlloy-Util-Parser-1 -lAlloy-C-Grammar-1 -lAlloy-C-Syntax-1 -lAlloy-C-IR-1 -lAlloy-C-Shim-1 -lAlloy-Util-Extension-1 -lAlloy-C-Extension-1 -lAlloy-Util-Syntax-1 -lAlloy-Util-Binder-1 -lAlloy-C-Command-1 -lAlloy-Util-Server-Capabilities-1 -lAlloy-Util-Server-Initialize-1 -lAlloy-Util-Server-Methods-1 -lAlloy-C-Server-Clangd-1 -lAlloy-Util-Server-Worker-1 -lAlloy-C-Server-Worker-1 -lAlloy-C-Server-Utils-1 -lAlloy-Util-Server-1 -lAlloy-C-Server-Hover-1 -lAlloy-C-Server-SemanticTokens-1 -lAlloy-C-Server-1 -lAlloy-C-1 -lStd-Tactic-OpenPrivate-1 -lStd-Tactic-NoMatch-1 -lStd-Data-List-Init-Lemmas-1 -lStd-Data-Array-Init-Basic-1 -lStd-Data-Ord-1 -lStd-Data-Array-Basic-1
error: stderr:
I'm assuming I have to do something additional?
Mac Malone (Aug 22 2023 at 23:42):
@Henrik Böving Actually that is a bug in Lake with precompiled modules. I did not include the module's moreLinkArgs
. Oops!
Henrik Böving (Aug 22 2023 at 23:43):
I shall await the next nightly then^^
Siddharth Bhat (Aug 22 2023 at 23:43):
@Tomas Skrivan I suspect this will fix our eigen bindings also!
Mac Malone (Aug 22 2023 at 23:43):
@Henrik Böving However, you should still be able to build the executable.
Henrik Böving (Aug 22 2023 at 23:43):
if I add the linker flags there?
Henrik Böving (Aug 22 2023 at 23:44):
let's see
Henrik Böving (Aug 22 2023 at 23:50):
No it does seem to forcibly want to link Socket before but that's fine I have time^^
Mac Malone (Aug 22 2023 at 23:52):
@Henrik Böving Could you try turning off precompileModules
? I want to verify my suspicion that that is the problem.
Henrik Böving (Aug 22 2023 at 23:52):
sure
Henrik Böving (Aug 23 2023 at 00:00):
Mac Malone said:
Henrik Böving Could you try turning off
precompileModules
? I want to verify my suspicion that that is the problem.
yes
Mac Malone (Aug 23 2023 at 00:05):
@Henrik Böving Yes, it worked without precompileModules
?
Henrik Böving (Aug 23 2023 at 00:05):
Yes
Mac Malone (Aug 23 2023 at 00:06):
@Henrik Böving Thanks! :thumbs_up:
Henrik Böving (Aug 23 2023 at 00:10):
(note that work means: it manages to pass the linker argument through, windows is of course ridiculing me and telling me that it cannot find that library)
Which is why i checked the docs and for some god-forsaken reason they (https://learn.microsoft.com/en-us/windows/win32/winsock/creating-a-basic-winsock-application) want you to do it like this:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main() {
return 0;
}
and i tried that:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main() {
return 0;
}
but alloy does not like the pragma syntax as it aborts at the "
of "ws2..." so that's another grammar issue for your^^ @Mac Malone
:fast_forward:
Mac Malone (Aug 23 2023 at 00:18):
@Henrik Böving Fixed.
Mac Malone (Aug 23 2023 at 00:31):
Also, lean4#2447
Siddharth Bhat (Aug 23 2023 at 01:51):
@Mac Malone does it suffice to checkout the latest lean, build it, and /path/to/checkout/bin/lake build
to test this?
Mac Malone (Aug 23 2023 at 01:52):
@Siddharth Bhat Sure, you shouldn't even need to build Lean itself, just building lake with a recent Lean toolchain should work.
James Gallicchio (Aug 24 2023 at 05:16):
So... suppose I wanted to be able to handle https traffic........ I assume there's a lot of work before socket.lean could support https? :stuck_out_tongue:
Henrik Böving (Aug 24 2023 at 08:02):
There are basically two requirements for this.
- Someone needs to write an HTTP parser. Parsing HTTP 1.1 is actually completely trivial and I claim most FP interested people on this server could get it done with parser combinators in a few days based on the RFC: https://www.rfc-editor.org/rfc/rfc2616 Implementing everything the standard tells you is another thing but many things in the HTTP 1.1 standard are very simple (deliberately). If we want a modern HTTP library we'll at least have to parse HTTP 2...if we want to do that you can throw the idea of "deliberate simplicity" completely out of the window since they employ lots funky mechanisms such as: Multiplexing multiple connections through the same socket as "streams, Compressing headers in such a way that you basically only get differential update on what headers changed and many more fun things. So getting a compliant HTTP 2 implementation is actually something where you kind of need to know what you are doing
- the TLS/SSL part, this is in theory easy as we "just need to bind OpenSSL" since it provides the necessary API for wrapping a regular socket with a TLS/SSL context such that the encryption/decryption just works :tm:. Then again binding OpenSSL especially in such a way that it is secure and safe is also not very trivial. However this second half can be ignored for a long while as it is rather common to have a reverse proxy like nginx today that receives the TLS connection which can then forward it to us in clear text.
@James Gallicchio
Sebastian Ullrich (Aug 24 2023 at 08:23):
Note that this topic originally was about making HTTP requests, not accepting them :) . For which, as pointed out, binding to libcurl should indeed be vastly easier.
Mac Malone (Aug 30 2023 at 07:31):
Joachim Breitner said:
After seeing your message I tried it in loogle (by changing the nix shell to use the clang-stdenv, so any problems may be nix-related), but I get
I just realized I somehow overlooked this message. Sorry! That error is unfortunately an expected one but fortunately should not actually cause any problems.
James Gallicchio (Sep 09 2023 at 19:22):
@Arthur Paulino I see Http.lean
has an http parser and the relevant types -- do you think we could separate those into a package independent of Socket
? (is the package worth reviving?)
Arthur Paulino (Sep 09 2023 at 19:24):
We're not maintaining the repo right now, but feel free to open PRs to organize it in a way that you see fit and I can review
Arthur Paulino (Sep 09 2023 at 19:26):
It's also, obviously, fine to maintain a fork of your own for the sake of agility on your side
James Gallicchio (Sep 09 2023 at 19:29):
(frankly, I don't really want to maintain an http library, so if lurk could maintain it longterm I'd prefer that, but I suspect you're not using it right now? :joy:)
James Gallicchio (Sep 09 2023 at 19:30):
I'll fork it for now, and we can figure out long term maintenance later
Sebastian Ullrich (Sep 12 2023 at 20:51):
Interesting JEP in the context of this thread: https://openjdk.org/jeps/454
Replace the brittle machinery of native methods and the Java Native Interface (JNI) with a concise, readable, and pure-Java API.
JNI involves several tedious artifacts: a Java API (native methods), a C header file derived from the Java API, and a C implementation that calls the native library of interest. Java developers must work across multiple toolchains to keep platform-dependent artifacts in sync, which is especially burdensome when the native library evolves rapidly.
James Gallicchio (Sep 13 2023 at 18:50):
Ok, I have updated and pretty much rewritten/overhauled the http library here: https://github.com/JamesGallicchio/http
Scott Morrison (Sep 13 2023 at 23:43):
Looks like you can remove the "When running lake update ..." note in the README!
James Gallicchio (Sep 13 2023 at 23:48):
wha-- I just put that there! :racecar:
James Gallicchio (Sep 13 2023 at 23:52):
wait, https://github.com/fgdorais/lean4-unicode-basic/blob/main/lake-manifest.json is still out of date
Scott Morrison (Sep 14 2023 at 00:06):
Sorry, my mistake!
Scott Morrison (Sep 14 2023 at 00:07):
Great example of the automatic version bumping / notification we need all across the ecosystem. :-)
James Gallicchio (Sep 14 2023 at 00:25):
if i make enough libraries on my way to the github bot, i'll have no path forward except through!
James Gallicchio (Sep 14 2023 at 00:26):
<---- I am a clown
Siddhartha Gadgil (Sep 14 2023 at 02:00):
@James Gallicchio
Is this ready to replace curl
calls? If so is there an example?
James Gallicchio (Sep 14 2023 at 02:29):
No -- part of the rewrite's purpose was to get rid of dependence on Socket.lean
. It only defines types for representing HTTP, not how to send them over the wire. The second half is honestly pretty straightforward to do from scratch, and is somewhat opinionated on what's the best API, so it makes sense to stay separate.
James Gallicchio (Sep 14 2023 at 02:30):
I can add some examples to the README. The types are fairly straightforward, but the documentation is definitely lacking...
Henrik Böving (Sep 14 2023 at 08:54):
James Gallicchio said:
No -- part of the rewrite's purpose was to get rid of dependence on
Socket.lean
. It only defines types for representing HTTP, not how to send them over the wire. The second half is honestly pretty straightforward to do from scratch, and is somewhat opinionated on what's the best API, so it makes sense to stay separate.
But you don't really want to have this separation with HTTP right? Like even very basic HTTP already has a concept of keeping connections alive and things like that.
Schrodinger ZHU Yifan (Sep 14 2023 at 13:07):
Henrik Böving said:
James Gallicchio said:
No -- part of the rewrite's purpose was to get rid of dependence on
Socket.lean
. It only defines types for representing HTTP, not how to send them over the wire. The second half is honestly pretty straightforward to do from scratch, and is somewhat opinionated on what's the best API, so it makes sense to stay separate.But you don't really want to have this separation with HTTP right? Like even very basic HTTP already has a concept of keeping connections alive and things like that.
I think separate abstraction is actually common?
https://crates.io/crates/http/0.2.9
Henrik Böving (Sep 14 2023 at 13:21):
Interesting I see
James Gallicchio (Sep 14 2023 at 15:22):
yeah an HTTP server is super complicated compared to anything in this package
Last updated: Dec 20 2023 at 11:08 UTC