Venant de Java, on dirait que V est le cousin de Kotlin (enfin j'y connais pas grand chose en C).
Venant de Java, on dirait que V est le cousin de Kotlin (enfin j'y connais pas grand chose en C).
Je doute que GCC -O3 (ou plus) remplace un malloc par une allocation sur la pile. Donc il transpile dans un mauvais code C. Pas vraiment le rève.
Quand au question par rapport au performance voici ce que dit son createur sur le benchmark:
N'importe qui ayant un peu de connaissance des compilateurs sait que ce n'est pas du toute pertinent. Son instruction va être compilée 1 fois et les 199 999 autres fois la version compilée de l'instruction sera récupérée à partir du cache (explicitement ou implicitement) .It's a bit silly, all it does is generate the following pair of statements 200 000 times:
a = 1
println(a)
En gros la seul chose qu'il prouve c'est que le démarrage de son compilateurs est plus efficace que les autres. Ce qui est logique, le compilo est plus léger et fait probablement moins de chose (en partie car apparemment non fini).
EDIT :
Sinon sur le langage en tant que tel, ça a l'air d'être un bon langage (à part les int qui sont forcément sur 32bits, ce qui fait qu'ils risquent de ne pas être optimisés sur toute les architectures). Son concepteur a essayé de faire un mix cohérent de l'état de l'art en manière de création de langage. Ce qu'il a plutôt bien réussi. Il manque évidemment une API standard j'imagine qu'il doit être possible de rendre les API C/C++ compatibles (De la même façon que les API Java sont disponibles en Scala, Celyon...)
Cependant, je doute très fortement qu'il ait un avenir. Sans une communauté ou une entreprise derrière c'est très compliqué de percer pour un nouveau langage.
Je ne comprend pas la remarque, tu fais des mallocs en C ou C++ c'est la même chose.
Et pourtant les compilers qu'il a testé mettent des durées délirantes (ou plantent) pour faire cela. Donc c'est plus compliqué que ça.N'importe qui ayant un peu de connaissance des compilateurs sait que ce n'est pas du toute pertinent. Son instruction va être compilée 1 fois et les 199 999 autres fois la version compilée de l'instruction sera récupérée à partir du cache (explicitement ou implicitement) .
Ce test a une importance limitée, mais non nulle. Certains projets sont vraiment impactés par la durée de compilation.
Dans la doc je vois :à part les int qui sont forcément sur 32bits, ce qui fait qu'ils risquent de ne pas être optimisés sur toute les architectures
i8 i16 i32 i64
u8 u16 u32 u64
Source: https://github.com/vlang-io/V/tree/master/examples
Example de générique en V:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 // Please share your thoughts, suggestions, questions, etc here: // https://github.com/vlang-io/V/issues/3 // I'm very interested in your feedback. module main struct User { /* ... */ } struct Post { /* ... */ } struct DB { /* ... */ } struct Repo <T> { db DB } // Generic code is notoriously verbose. To reduce clutter, V doesn't require you // to add `<T>` every time, since it already knows that Repo is a generic type. fn new_repo<T>(db DB) Repo { return Repo<T>{db: db} } // This is a generic function. V will generate it for every type it's used with. fn (r Repo) find_by_id(id int) T? { // `?` means the function returns an optional table_name := T.name // in this example getting the name of the type gives us the table name return r.db.query_one<T>('select * from $table_name where id = ?', id) } fn main() { db := new_db() users_repo := new_repo<User>(db) // I'm also considering passing the type as an argument // users_repo := new_repo(User, db) posts_repo := new_repo<Post>(db) user := users_repo.find_by_id(1) or { eprintln('User not found') return } post := posts_repo.find_by_id(1) or { eprintln('Post not found') return } }
Si la réponse vous a aidé, pensez à cliquer sur +1
C'est ce que devait penser les grosses boites IT lors des débuts de Linux
V vu sa taille et sa rapidité, il pourrait avoir plusieurs utilisations:
- pourrait-on l'utiliser et le mettre en cache de browser tel le webassembly?!
- l'utiliser comme langage ioT
- l'utiliser pour des fonctions critiques de Python au lieu d'utiliser le C, PyPi
- comme plugin pour des outils de 3D, dessin
- mining
Si la réponse vous a aidé, pensez à cliquer sur +1
Un code GO avec GTK+
Donc le code V devrait ressembler à cela.
(P.S.: j'ai encore du mal à voir les grosses différences)
https://mattn.github.io/go-gtk/
Si la réponse vous a aidé, pensez à cliquer sur +1
Quelle que soit la manière à laquelle on ajouterait de la métaprogrammation à un langage qui n'en a pas, cela reviendrait à créer un nouveau langage qui serait un sur-ensemble de l'ancien. Et en plus, la syntaxe de ce nouveau langage serait extensible, ce qui contredirait deux objectifs du langages V : rester simple et compiler vite.
Et alors ? Parmi les nouveaux langages qui apparaissent régulièrement, il y a peu de survivants. Parmi les langages sans ramasse-miettes que personne ne connaît, on a déjà :
- Cyclone, un langage qui n'est plus maintenu (d'après sa propre doc),
- Loci, un langage qui s'inspire beaucoup du C++, mais qui utilise le sous-typage structurel pour le polymorphisme au runtime,
- Jai, un langage dont l'auteur se focalise sur le développement de jeux vidéo,
- C2, un langage conçu par des gens qui n'aiment pas l'abstraction,
- Zig, un langage dont j'ai appris l'existence avant-hier en lisant la doc du langage V et
- beaucoup d'autres.
Heu... pas du tout. Au début de linux, on avait besoin d'un noyau libre et linux était à peu près le seul disponible : minix n'était pas libre, hurd n'était qu'un projet de labo, 386BSD était en proces avec AT&T... C'est même Linus qui le dit : "He has stated that if either the GNU Hurd or 386BSD kernels had been available at the time, he likely would not have written his own" (https://en.wikipedia.org/wiki/Histor...ux#cite_ref-10). Les grosses boites ont rapidement cru à linux : IBM, Compaq, Oracle, Netscape, etc supportaient Linux dès 98 alors que la version 1.0 n'avait que 4 ans.
Donc non, ça n'a rien à voir avec les langages potentiellement concurrents de V qui eux sont nombreux : go, crystal, nim, vala, rust, D, ada...
En tout cas, bravo au créateur de V pour l'opération de communication. Réussir à générer autant de buzz avec un langage dont personne n'a jamais compilé une seule ligne, c'est fort...
Sauf que dans la plupart des cas en C, on fait un allocation sur la pile (et non dans le tas comme malloc) :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 struct User u1;// allocation sur la pile, plus perfomant. A éviter avec des gros objets struct User *u2= malloc (sizeof (struct User));// allocation sur le tas, plus lents car localisé ailleur. A utiliser quand on a de gros objets et qu'on veut éviter des copies couteuses ou d'exploser la taille de la pile. A utiliser également quand on veut return un pointeur.
Qu'il ait une importance non nulle ok mais il faut pas le sur interpréter. Jusqu'à une véritable preuve du contraire (un benchmark pertinent), non, en condition réelle il n'est pas plus performant (ni moins performant).
Je parle du type int. Les langages comme C adaptent le type int à la taille du "mot" (32bits ou 64bits sur les CPU récent), ça rend les accès/opérations plus performantes (en théorie) car plus simples/natives. Le créateur à fait le choix (que je respect) d'avoir un type int consistent et prédictible. Mais ça peut avoir un coût d'un point de vue performance.
J'ai qu'en même espoir en ce langage dès qu'on aura résolu cette question qui me turlupine : que va t'il apporter en plus que GO ?
Hormis le fait qu'il soit léger et qu'il pourrait s'intégrer comme plugin.
GO est également simple et rapide, d'ailleurs je devrais m'y intéresser lol.
En informatique comme dans d'autres domaines, pour que quelque-chose ait du succès, il faut principalement que ce soit la bonne période.
C'est comme les semences, si l'on sème en hiver, ça ne poussera pas
Pas que ce soit le plus joli ou le plus parfait des langages (comme VB rofl) mais la bonne période et le besoin de cette invention qui pourra ensuite donner naissance à autre chose (comme ce fut le cas du C#).
Dans la période du big data, s'opposant à python, alors que d'autres ont déjà tracé la route comme GO, rust... pourquoi pas!
Mais il lui faudrait quelques librairies comme l'accès aux bases de données, au drawing (dessin: graphes et images), à l'encryption, au web (bien que http_get soit déjà là), au math.
Si la réponse vous a aidé, pensez à cliquer sur +1
@Mathieu Vergne : j'adore ton commentaire, tu te permets de juger sans avoir même parcouru la documentation de quelques pages. Ton titre d' "expert éminent" me parait largement usurpé
Je vois le langage V un peu comme ce qu'était le langage C à ses début (K&R) : simple, fiable, rapide et maîtrisable. Le V rajoute certaines techniques modernes de prog sans en faire trop et devenir imbuvable. Ça me plait.
Comme je disais précédemment : il le fait juste à des fins de démonstration je suppose. Evidemment il faut allouer sur la pile quand on le peut. Là il montre juste une allocation sur le tas, juste pour montrer.
Tu prends le parti de croire que le développeur ment, c'est ton choix. Moi je pense qu'il dit la vérité, parce que c'est crédible et qu'il a plus à y perdre qu'à y gagner. De toutes manières on verra bien à la sortie.
Il ne me semble pas qu'utiliser du i32 ait un impact en performances sur du intel x64. Par contre ça économise de la place au niveau des instructions et en mémoire. Perso ça me choque pas.
C'est dingue. Y'a des gens qui défendent corps et âme un langage qu'on n'a pas pu tester et que seul la "doc" (qui fait plus office de publicité que de doc) décrit. Si je vous dis que j'ai un inventé tout seul un langage, simple, puissant, expressif, memory safe, "data race" free, avec un actor model integré et le tout avec des temps de compilation hyper rapide en produisant du code aussi rapide que le C, vous me croyez aussi ?
C'est possible d'avoir du polymorphisme sans "dynamic dispatch" ?
Je serais curieux de savoir comment il s'y est pris pour que son exemple fonctionne sans dynamic dispatch...
Une implémentation en C "objet" avec dynamic dispatch :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 #include <stdio.h> typedef struct _SPEAKER SPEAKER; typedef char* (*SPEAK)(SPEAKER*); struct _SPEAKER { SPEAK lpSpeak; }; typedef struct _DOG { SPEAKER speaker; } DOG; typedef struct _CAT { SPEAKER speaker; } CAT; char* DogSpeak(SPEAKER* lpThis) { return "woof"; } char* CatSpeak(SPEAKER* lpThis) { return "meow"; } void CreateDog(DOG* lpDog) { lpDog->speaker.lpSpeak = &DogSpeak; } void CreateCat(CAT* lpCat) { lpCat->speaker.lpSpeak = &CatSpeak; } void perform(SPEAKER* lpSpeaker) { puts(lpSpeaker->lpSpeak(lpSpeaker)); } int main (int argc, char *argv[]) { DOG dog; CAT cat; CreateDog(&dog); CreateCat(&cat); perform(&dog.speaker); perform(&cat.speaker); return 0; }
Le mec nous vend un peu du rêve 'Automatic memory management' sans GC, 'Fearless concurrency'... mais ça semble être plus des projets que du concret.
[edit : modification du code pour gérer "this" et suppression de la "vtable"]
Oui. Quand le type de l'argument est connu à la compilation, le dispatch peut être fait par le compilateur au lieu d'être repoussé au runtime.
Dans mon exemple en C++, il y a du polymorphisme (car le code du template de fonction perform marche pour plusieurs types) et c'est lors de la compilation du code qui appelle perform que le compilateur fait le dispath pour savoir laquelle des deux fonctions speak il faut appeler.
Pour te renseigner, tu peux chercher les mot-clefs suivants :
- surcharge de noms de fonction et
- programmation générique
Avant de te faire une opinion là-dessus, je conseille la lecture des chapitres suivants de The Rust Programming Language :
Ça dépend comment on interprète automatic memory management mais, dans les langages sans ramasse-miettes, ça fait longtemps qu'on sait faire mieux que le C.
D'accord mais ça me paraît très restrictif.
Bon déjà, connaître toutes les implémentation de Speaker au moment de la compilation, ça veut dire qu'on ne peut pas faire de bibliothèques (.so, .dll...) et d'extensions.
Par exemple une bibliothèque qui propose fn perform(s Speaker);, c'est pas possible car on ne connaît pas d'avance tous les animaux.
Mais surtout, comment tu gères des cas tout bêtes tels qu'un tableau de Speaker ? Quelque chose comme :
Ça fait un moment que je pense jeter un œil à Rust mais j'imagine qu'il impose des contraintes au code que l'auteur de V aurait déjà dû mettre en place.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 for speaker in speakers { perform(speaker); }
Par exemple le code suivant ne compile pas en Rust alors que l'équivalent compile dans la plupart des autres langages :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 let s1 = String::from("hello"); let s2 = s1; println!("{}, world!", s1);
Même avec du polymorphisme statique (c.-à-d. qui se fait à la compilation et pas au runtime), c'est possible, mais une partie de la bibliothèque n'est pas compilée à l'avance. Par exemple, en C++, la bibliothèque standard et Boost contiennent une tonne de templates. Mais ces templates ne sont pas compilés sous forme de ".so" ou ".dll" : quand le compilateur compile du code qui utilise des templates, il doit accéder au code source de ces templates.
Là, par contre, si on veut que le tableau puisse contenir des éléments hétérogènes dont on ne connaît le type qu'au runtime, alors il faut bien utiliser une indirection au runtime avec des pointeurs de fonction ou une abstraction qui utilise des adresses de fonctions sous le capot (par exemple des tables virtuelles).
Parmi les langages capables de faire du polymorphisme statique, tous ceux que je connais permettent de faire aussi du polymorphisme au runtime.
Ici, let s2 = s1; fait un transfert de ressource de s1 vers s2, donc s1 n'est plus utilisable. Mais ce n'est que de la syntaxe.
Si tu veux une sémantique de référence, il faut écrire :
Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 fn main() { let s1 = String::from("hello"); let s2 = &s1; println!("{}, world!", s1); }
Si tu veux une copie, il faut écrire :
Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 fn main() { let s1 = String::from("hello"); let s2 = s1.clone(); println!("{}, world!", s1); }
Déterrage de topic pour signaler que le langage est sortie.
Comme on pouvait facilement s'en douter (sauf pour quelques personnes naïves) le langage et compilateur n'est pas du tout à la hauteur de ce qui est annoncé.
Entre autre, un hello world leak 4Mo de données et le langage n'est pas safe du tout. Pour ceux que ça intéresse, vous pouvez voir quelques retours ici.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager