Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard library documentation #1

Merged
merged 26 commits into from
Apr 26, 2020
Merged

Conversation

BenjaminNavarro
Copy link
Collaborator

Creating a PR now so that I can get early feedback.

So far, I just created the pages listed in Feral-Lang/Feral#8. I'll start enumerating what's available in each module and then we can see what's the best way to organize it

@BenjaminNavarro
Copy link
Collaborator Author

@Electrux
Copy link
Contributor

Looks great! 😁
Just added a little comment.

@BenjaminNavarro
Copy link
Collaborator Author

I started with the IO module. Could you tell me if you like it like this?

I'm still unsure about the presentation of the functions signature. Do you prefer a leading or trailing return type? Should I also specify the type of the arguments if it is relevant?

@Electrux
Copy link
Contributor

Ooh! It looks fantastic! Far better than what I'd have come up with, that's for sure! 😱
The format (including return type) looks just perfect as is!
Yes, I think it would be appropriate to specify argument type(s) where relevant. The reason being that for a lot of functions (see in os module, for example), the arguments are not really obvious and one would have to dig into the source if they want to use a function of that nature.

Also, I wonder if there is some tool (besides doxygen) that could parse and auto generate markdown from c++ source files. In that case, we could simply make and update the function reference while working on it to avoid a lot of manual work. Do you know of any software of that sorts? If not, perhaps we could employ doxygen, or if worthful, create a translator (from C++ comments to markdown) in Feral itself 🤔.
Also, in such case, having a separate API reference would be quite valuable.

What are your thoughts on this?

@BenjaminNavarro
Copy link
Collaborator Author

Glad that you like it 😃

I'll add the types, no problem.

I first thought about autogenerating the doc from source code comments but I don't know of a tool which can generate markdown files (Doxygen output is HTML and LaTeX only I think). Moreover, it is easier for people to contribute to the documentation if the only thing they have to do is fork the Book repo, make some changes (can be done from GitHub directly) and create a PR. And they don't have to mess with the source code, which is probably a good point. This is more or less what they do for the Godot game engine, with the docs being on a separate repo and generated (sphinx) based on a mix of hand written and autogenerated rst files. The autogenerated ones are based on hand written xml files describing the API doc (this part is quite ugly tbh)
The only concern with this approach is that it's easier to forget to document an addition to the standard library (although this can be enforced when a PR is submitted) but on the other side, you can make a function documentation as long as you want with multiple code examples without hurting code readability. But maybe there should still be a minimal doxygen doc on the C++ side for the developers.

I don't known, I don't have a perfect answer for all of this, lot of possibilities...

@Electrux
Copy link
Contributor

Oh yes! That seems to be the best option. Have a proper document in the book and a (much) smaller autogenerated API reference in the source code.
The autogenerated could be done by doxygen or something and would not interact with the Book whatsoever.
Your point is absolutely valid and quite important that modifications in the book can simply be done by forking the repo.
Thanks for the input 😁.

@BenjaminNavarro
Copy link
Collaborator Author

You're welcome!

I just pushed updates for the IO module.

@Electrux
Copy link
Contributor

Ooh! Looks really nice! Amazing work!!
Thanks a lot 😁

@BenjaminNavarro
Copy link
Collaborator Author

Just quick question, what are the native type names? Here I can see that each type is defined with and without a trailing _t but I don't know which one should be presented to the user.

@Electrux
Copy link
Contributor

okay, so... set_typename is what a user sees when they call the .str() member function on an object of class. The Feral VM tries to find the name (if it exists) from type ID, if no name exists, the .str() function will show as typeid<x> where x is the typeid of the type.
The _t variants, on the other hand, are the names of special variables that are created when a type is registered here for example. These variables represent the types themselves, and are used to (usually) bind functions to those types (ie. member functions).
Hope that makes sense 🤔

@BenjaminNavarro
Copy link
Collaborator Author

It does, thanks. So I should use the _t variant to document the types in the API?

@Electrux
Copy link
Contributor

no, since _t variants are actually variables themselves and not names of types, that would be technically incorrect 🤔
Just the names would be perfectly fine 😁

@Electrux
Copy link
Contributor

Electrux commented Apr 13, 2020

Great updates! A couple things though:

  1. The Structs and Enums chapter should actually be Lang since that's the name of the module (std.lang).
  2. In strings chapter:
    1. The sentence There is no character type in Feral and so are represented are one character strings. seems grammatically incorrect (I think it should be There is no character type in Feral and so are represented as one character strings.)
    2. In function signatures, the function names are sometimes prepended with string. and sometimes they are not (push() vs pop()). I think it would be best to just prepend it for every member function name.

Again incredible work! Thanks a bunch! ❤️

@BenjaminNavarro
Copy link
Collaborator Author

  1. Ok I will change the chapter name.
    1. Yep that's a typo right here, will fix.
    2. Yes I missed that ones, thanks for catching that. I initially didn't put anything before the function name but then I got to i_to_c() which is defined on int so I figured it would be better to prepend the type to the function names

@Electrux
Copy link
Contributor

Electrux commented Apr 14, 2020

wow! cool work on the std.lang module 😱
The examples are really awesome!!!!

By the way, how has been your experience understanding the language till now?
What are the things that can be improved? If there is a lot, please do certainly create an issue about it.

Thanks for the fantastic work 😁

@BenjaminNavarro
Copy link
Collaborator Author

BenjaminNavarro commented Apr 14, 2020

You're welcome! I find examples usually more important than the text surrounding them and often what people will look at first, so I focus on that a bit more than the rest.

For now, with my (I hope) good C++ knowledge I can follow quite easily what's going on in the std but for things really language related, I often have to test things to see what works and what doesn't because the docs are still missing 😄

EDIT: I just looked at map.new() and I find it strange to pass all the key/value pairs like key1, value1, key2, value2 instead of key1 = value1, key2 = value2 just like with structs

@Electrux
Copy link
Contributor

That's cool 😁. Glad to know that the C++ codebase is at least legible 😂.

About the map.new(), the reason I didn't go with key1 = value, ... format is because that is the syntax of keyword arguments which requires that LHS (key1) be parsed as is instead of being an identifier or expression.
That said, I also think that it could be improved in some way, perhaps something like key1: value1, granted, that will require some additional work on parser as well as bytecode generation stages 🤔.

If you have suggestions regarding that, please do let me know.

@BenjaminNavarro
Copy link
Collaborator Author

Ok I see. Another option, although a bit verbose, would be to use arrays to group key/value pairs. eg. map.new([key1, value1], [key2, value2], ...). That should be doable right now because array are heterogeneous so you don't loose the key type information but I don't know if it's a good solution or not.


The **lang** module offers a way to create user-defined structures and enumerations.

A structure can pack together variables and functions, which allow object-oriented programming.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allows

```
lang.struct(field = value, ...) -> type
```
Creates a new structure type type holding a set of `field`s. The given `value`s are used to infer the type of each field and as default values during construction. The return type can be used to instantiate objects of this type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returned

```
Creates a new structure type type holding a set of `field`s. The given `value`s are used to infer the type of each field and as default values during construction. The return type can be used to instantiate objects of this type.

Adding member functions to a type is done with the `let func in type = fn(args) {}` construct, with `func` being the function's name. Inside the function, variables and functions belonging to the type can be accessed using the `self` keyword.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

semicolon after {}

The **str** module defines member functions for the native `string` type and other string manipulation related functions.
The functions available natively in the language can be consulted [here](/13-core-functions.html#string).

A `string` is a sequence of characters. There is no character type in **Feral** and so are represented are one character strings.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so are represented as

```
vector.slice(start: int, end: int = -1) -> vector
```
Extracts the elements from `start` to `end - 1` and returns them in a new vector. If `end == -1` then the slice ends at the end of the vector
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may wanna add:
any modification in the elements of a slice will affect its original vector as well

@@ -0,0 +1,177 @@
# Maps

The **map** module defines the `map` type and all the vector manipulation related functions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vector map

{Answer?: 42, 0: Zero, 1: One}
```

Note that the elements are not stored in the order they are given. They are lexicographically sorted
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not sorted at all - c++'s unordered_map.
From cppreference's unordered_map page:

Internally, the elements are not sorted in any particular order, but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key. This allows fast access to individual elements, since once the hash is computed, it refers to the exact bucket the element is placed into.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I was probably thinking of std::map when I wrote this

@Electrux
Copy link
Contributor

Just read it. Added some comments.
Awesomely written, as always 😁

@BenjaminNavarro
Copy link
Collaborator Author

Thanks for the comments, I'll address them

@@ -122,6 +122,6 @@ io.println(hello[5]);

Output:
```
h
!
(nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umm... (nil) should have been ! and h should be as it is 😛

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦

@@ -40,7 +40,7 @@ Gives the output:
{Answer?: 42, 0: Zero, 1: One}
```

Note that the elements are not stored in the order they are given. They are lexicographically sorted
Note that the elements are not stored in any particular order and thus does not necessarily follow the given one
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thus does not thus do not

@@ -1 +1,175 @@
# Builder

The **builder** module defines a `builder` type that allows to build and install C++ modules to be used with Feral
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builder_t type

install C++ modules install external modules
(because it's not C++ exclusive, it can install Feral only modules too)


The **builder** module defines a `builder` type that allows to build and install C++ modules to be used with Feral

A guide on how to write and build modules for Feral can be read [here](https://levelup.gitconnected.com/writing-c-modules-for-feral-391c30ac7739).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


### new
```
builder.new() -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


Possible output:
```
typeid<14>{linker_flags: , lib_flags: -lferalvm -lgmpxx -lgmp -lmpfr , lib_dirs: -L/usr/lib -L/usr/local/lib/feral , srcs: , ccache: /usr/bin/ccache , compiler: g++, is_dll: false, compiler_opts: -std=c++11 -O2 , inc_dirs: -I/usr/include }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in commit 50217df of Feral-Std, added typename for builder_t so now it will show builder_t instead of typeid<14>


### make_dll
```
builder.make_dll() -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


### add_comp_opts
```
builder.add_comp_opts(opt: string) -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


### add_inc
```
builder.add_inc(inc_dir: string) -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


### add_lib
```
builder.add_lib(lib_flag : string, lib_dir = '' : string) -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


### add_src
```
builder.add_src(src: string) -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> builder -> builder_t


### perform
```
builder.perform(output_file: string, .kw_args) -> builder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returns integer, not builder_t
(0 = success, fail otherwise)

@@ -24,7 +24,7 @@ let sys = import('std/sys');

### new
```
builder.new() -> builder
builder.new() -> builder_t_t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_t_t 😂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️ Damn, seems I didn't turn on the 'whole word' option when doing the search and replace...

@BenjaminNavarro BenjaminNavarro marked this pull request as ready for review April 26, 2020 06:47
@Electrux
Copy link
Contributor

So awesome work!! Thanks a lot! ❤️

@Electrux Electrux merged commit e61582b into Feral-Lang:master Apr 26, 2020
@Electrux
Copy link
Contributor

okay merged and built. It's available now 😁
https://feral-lang.github.io/Book

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants