60

euh à part que je comprends rien (<< je suppose que c'est pas un shift logique ? cheeky), je te rappelle juste que si on a fait tout ce bidouillage c'est dans l'unique but d'optimiser en s'arrêtant à racine(n), ce que tu n'as pas l'air de faire. Bon peut-être que ça ne compliquerait pas beaucoup ton code de le faire j'en sais rien mais voilà quoi ^^
parce que sinon moi je peux faire ça aussi :
let rec est_non_premier n = function [] -> false | p :: suite -> n mod p = 0 || est_non_premier n suite
let ajoute_prochain_premier = function [] -> [2]
  | p::suite as liste -> let rec aux n liste = if est_non_premier n liste then aux (n + 1) liste else n in aux (p + 1) liste :: liste
let premiers_premiers n = let liste = ref [] in for i = 1 to n do liste := ajoute_prochain_premier !liste done; !liste

ce qui est déjà plus compréhensible que ton charabia cheeky
et on peut peut-être faire plus court avec des fonctions de la lib standard, je vais regarder ça tiens
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

61

oups j'ai oublié de le mettre cheeky

infinity=1.0/0
primes=[2]
n=ARGV.shift.to_i
(n-1).times {
    primes << (primes[-1]+1..infinity).find{|n|
        s=Math.sqrt(n).floor
        primes.find{|p| n%p==0&&[] || p>s&&[n] }[0]
    }
}
p primes


Et puis moi aussi je peux jouer à tout mettre en une seule ligne et ne pas faire d'entrées/sortie tongue
l=[2];(n-1).times{l<<(l[-1]+1..1.0/0).find{|n|l.find{|p|n%p<1&&[]||p*p>n&&[n]}[0]}}

EDIT : oups

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

62

Variante qui d'après ce que j'ai compris de ton code y ressemble davantage :
let premiers_premiers n = let liste = ref [2] and p = ref 2 in
for i = 0 to n - 1 do while List.exists (function x -> !p mod x = 0) !liste do incr p done; liste := !p :: !liste done; !liste
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

63

Je ne joue pas à tout mettre en une seule ligne, j'ai la flemme d'aller à la ligne c'est tout cheeky
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

64

Pas tutafé : tu testes les nombres à l'envers, donc ça augmente énormément le temps de calcul...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

65

euh, énormément tant que ça ? confus
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

66

Bah écoute, ça veut dire que pour 1 nombre sur 2, y aura N itérations au lieu de 1; pour 1 sur 3 parmi le reste, N-1 au lieu de 2; etc...

Ca veut dire que ton algo est en O(MaxPrime * NumPrimes), au lieu d'être en O(MaxPrime * foo(NumPrimes)) avec foo(x) genre ln(x)...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

67

Moui c'est vrai... d'où l'intérêt du truc de Moumou-Flanker
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

68

d'où l'intérêt d'utiliser une vraie classe de tableau ^^ (pas l'espèce de shblurg de Caml)

les listes chaînées ça pue, et en plus c'est affreusement lent (ça bouffe plus de RAM et surtout c'est complètement impossible à paralléliser, donc ça a des performances de merde sur les processeurs récents et cette tendance s'accentuera dans le futur embarrassed)

Alors qu'à moins d'avoir besoin du partage des fins de liste (où alors c'est intéressant, mais c'est un besoin très très spécifique qui est rarement nécessaire), les tableaux ont les mêmes propriétés asymptotiques que les listes sans effet de bord... (avec en plus accès aléatoire, insertion en O(1) en début *et* en fin de liste, performances bien supérieures, coût en RAM plus faible...)


Par contre les listes mutables avec effets de bords peuvent être utiles (insertion en O(1) n'importe où), mais c'est généralement pas de ça que le caml-zealot de base parle... (et avec le modèle non-OO de caml, c'est complètement inutilisables sans faire plein de contorsions)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

69

euh j'ai jamais dit que c'était une bonne idée d'utiliser une liste chaînée pour le présent problème et je ne l'ai jamais pensé non plus hein... mais Moumou-Flanker a parlé de listes chaînées *avant* de parler de nombres premiers...
et si caml a un problème, c'est bien que la stdlib est minimaliste par rapport à des langages « commerciaux » :-\ (je pense qu'on peut faire la même chose que ce que tu montres en ruby très facilement, à condition d'avoir implémenté la structure qui va bien ^^)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

70

Il n'y a pas que ça sad Cf les nombreuses critiques que j'ai déjà faites (filtrage trop bas-niveau, pas de surcharge...), qui font que Caml est assez mal adapté si tu veux avoir un certain nb de structures de données... A moins bien sûr de vouloir te taper une syntaxe très lourde (MapFromStringToInt.get_item env "blah" vs env["blah"])

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

71

Pourtant, dans la pratique, le code caml est plutôt compact.

Bref, #pipo#
Les droits inaliénables du troll :
1) le droit d'avoir raison
2) le droit d'être péremptoire
3) le droit de ne pas lire
4) le droit de ne pas répondre
5) le droit d'être de mauvaise foi
6) Autant pour moi / Faignant / Vivent Tintin et Milou

72

Comme le montre l'exemple de ce topic trigic ("ah oui nan mais là c'est une exception")

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

73

ah parce que le code du ./62 tu trouves ça pas compact toi ? confus (et franchement même mes exemples d'avant, sachant qu'ils contiennent la définition de la structure et des opérations de base dessus, je les trouve pas spécialement verbeux neutral)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

74

Non, c'est plutôt compact (pour du caml, bien sûr grin tu te fais chier à recopier 50x la même liste de paramètres à cause de la récursivité terminale, etc...), mais c'est vraiment *le* modèle de base de caml (la liste chaînée), et il y a des features du langages fait à peu près exprès pour (filtrage...)

Le problème c'est que c'est assez mal foutu, par exemple on voit que tu as hardcodé la structure de données en réimplémentant 2x la routine de parcours d'une liste : résultat, du code plus lourd, moins maintenable...

En Ruby, si tu fais :
class LinkedList
    attr_accessor :head,:nxt
    def initialize(v); self.head=v; end
end
class FullList
    include Enumerable
    def each(&block)
        ptr=@head
        while ptr
            yield ptr.head
            ptr=ptr.nxt
        end
    end
    def <<(val)
        nxt=LinkedList.new val
        @tail && @tail.nxt=nxt
        @head||=nxt
        @tail=nxt
        self
    end
    def last; @tail.head end
    def inspect; to_a.inspect end
end
primes=FullList.new<<2

à la place de
primes=[2]
alors tu peux réutiliser entièrement le code précédent, y compris le code qui affiche le résultat (en remplaçant quand même primes[-1] par primes.last, puisqu'il n'y a plus l'accès aléatoire; si tu y tiens tu peux faire une méthode qui s'appelle self.[] avec un cas particulier pour n=-1 et il n'y aura alors rigoureusement rien à changer), chose que tu ne pourrais absolument pas faire avec ton code... (qu'est-ce que tu fais si tu veux utiliser un tableau genre std::vector en C++ dans ton code Caml ? tu vas avoir plein plein de choses qui vont changer partout, et ça sera presque aussi lourd que tout refaire de zéro... pense à ce qui se passerait si c'était pas un bête algorithme de recherche de nombre premier, mais un vrai truc compliqué couic)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

75

ben si je faisais un vrai truc compliqué je le ferais plus modulaire ^^ (soit avec des objets, soit avec des modules paramétrés love, en fait j'avais commencé à faire ça pour mon tit prog d'othello sur une bouteille de Klein mais bon vu que je l'ai laissé en plan ça sert pas à grand chose que ça soit modulaire pour l'instant y a rien dedans cheeky)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

76

Justement, alors la mesure pertinente ne serait pas de regarder si le code version quick&dirty est compact, mais si le code version propre l'est smile

En attendant, je crois qu'il faut transformer le post d'hippo en :
Pourtant, dans la pratique, le code caml est plutôt crade et impossible à maintenir parce que sinon il serait trop verbeux.

où là je ne peux que crayonner trigic

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

77

bah regarde ça si tu veux (je crois que c'est la dernière version, je garantis pas que ça compile) :
c'est pas encore aussi modulaire que j'aurais voulu mais je trouve vraiment pas ça spécialement verbeux (bon évidemment les déclarations de signatures prennent plein de place mais tu ne les fais qu'une fois pour le coup, si comme j'en avais l'intention j'avais fait n types de plateaux différents la signature ne serait quand même là qu'une fois ^^)[nosmile]
type couleur = Blanc | Noir | Aucun
let autre_couleur = function Blanc -> Noir | Noir -> Blanc | _ -> invalid_arg "autre_couleur"

module Plateau : sig
  type case
  type direction
  type t
  val cree : unit -> t
  val clone : t -> t
  val directions : direction list
  val neg_dir : direction -> direction
  val avance_dir : case -> direction -> case
  val mult_dir : int -> direction -> direction
  val contenu_case : plateau: t -> case: case -> couleur
  val set_contenu_case : plateau: t -> case: case -> couleur: couleur -> unit
  val iter_cases : (case: case -> unit) -> unit
  type event = Case of case | Clic | Quit
  val init_dessin : unit -> unit
  val redessine : case: case -> couleur: couleur -> unit
  val attend_clic : unit -> event
end = struct
  type case = int * int
  type direction = int * int
  type t = couleur array array
  let cree () =
    let plateau = Array.make_matrix 8 8 Aucun
    in plateau.(0).(0) <- Blanc; plateau.(7).(7) <- Noir;
    plateau.(7).(0) <- Noir; plateau.(0).(7) <- Blanc; plateau
  let clone plateau = Array.map Array.copy plateau
  let directions = [0, 1 ; 1, 0 ; 1, 1; 1, -1]
  let neg_dir (a, b) = -a, -b
  let mult_dir i (a, b) = i * a, i * b
  let reduit (x, y) = (if y land 8 = 0 then x else lnot x) land 7, y land 7
  let avance_dir (a, b) (c, d) = reduit (a + c, b + d)
  let contenu_case ~plateau ~case:(x, y) = plateau.(x).(y)
  let set_contenu_case ~plateau ~case:(x, y) ~couleur = plateau.(x).(y) <- couleur
  let iter_cases f = for x = 0 to 7 do for y = 0 to 7 do f ~case:(x,y) done done
  open Graphics
  type event = Case of case | Clic | Quit
  let redessine ~case:(x, y) ~couleur =
    (match couleur with
      Blanc -> set_color white
    | Noir -> set_color black
    | _ -> set_color red); 
    fill_circle (x * 22 + 11) (y * 22 + 11) 9;
    fill_circle (x * 22 + 189) (y * 22 + 11) 9;
    fill_circle ((7 - x) * 22 + 11) (y * 22 + 189) 9;
    fill_circle ((7 - x) * 22 + 189) (y * 22 + 189) 9
  let init_dessin () =
    open_graph " 355x355+20+20"; (* " 363x382+20+20" pour win2k *)
    set_window_title "Othello en bouteille de Klein";
    set_color (rgb 0 128 64);
    fill_rect 0 0 354 354;
    set_color black;
    let quadrille i =
      moveto i 0;
      lineto i 355;
      moveto 0 i;
      lineto 355 i;
    in for i = 0 to 8 do
      quadrille (i * 22);  
      quadrille (178 + i * 22)
    done;
    quadrille 177;
    redessine ~case:(0,0) ~couleur:Blanc;
    redessine ~case:(0,7) ~couleur:Blanc;
    redessine ~case:(7,0) ~couleur:Noir;
    redessine ~case:(7,7) ~couleur:Noir
  exception Rien
  let rec attend_clic () =
    let status = wait_next_event [Button_down; Key_pressed] in
    if status.key = 'q' then Quit
    else if status.button = true then
      let reduit coord =
	if coord < 0 || coord > 354 then raise Rien
	else if coord < 176 then coord / 22, false
	else if coord < 178 then raise Rien
	else (coord - 178) / 22, true in
      try
	let y, neg = reduit status.mouse_y
	in let x, _ = reduit status.mouse_x
	in Case (if neg then (7 - x, y) else (x,y))
      with Rien -> Clic
    else attend_clic ()
end

let (+:) = Plateau.avance_dir
let ( *: ) = Plateau.mult_dir

module Coups : sig
  type coup
  val case : coup -> Plateau.case
  val trouve : couleur: couleur -> plateau: Plateau.t -> coup list
  val joue : coup: coup -> couleur: couleur -> plateau: Plateau.t -> unit
end = struct
  type ligne = Simple | Double | Non
  type coup = Plateau.case * (Plateau.direction * int) list
  let case = fst
  let trouve_ligne case_depart ~direction ~couleur ~plateau =
    let case = case_depart +: direction in
    if Plateau.contenu_case ~plateau ~case <> autre_couleur couleur then Non, 0
    else
      let rec continue i nombre =
	let case = case_depart +: i *: direction in
	if case = case_depart then Double, nombre
	else
	  let pion = Plateau.contenu_case ~plateau ~case in
	  if pion = couleur then Simple, nombre
	  else if pion = Aucun then Non, 0
	  else continue (i + 1) (nombre + 1)
      in continue 2 1
	
  let trouve_coup ~case ~couleur ~plateau =
    let directions_trouvees = ref [] in
    let cherche_lignes direction =
      let (ligne, nombre) = trouve_ligne case ~direction ~couleur ~plateau in
      if ligne <> Non then
	directions_trouvees := (direction, nombre) :: !directions_trouvees;
      if ligne <> Double then
	let dir = Plateau.neg_dir direction in
	let (ligne, nombre) = trouve_ligne case ~direction:dir ~couleur ~plateau in
	if ligne <> Non then
          directions_trouvees := (dir, nombre) :: !directions_trouvees;
    in List.iter cherche_lignes Plateau.directions; match !directions_trouvees with
      [] -> None
    | directions -> Some (case, directions)
	  
  let trouve ~couleur ~plateau =
    let resultat = ref [] in
    let ajoute_coup ~case =
      if Plateau.contenu_case ~case ~plateau = Aucun then
	match trouve_coup ~case ~couleur ~plateau with
	  Some coup -> resultat := coup :: !resultat
	| _ -> ()
     in Plateau.iter_cases ajoute_coup; !resultat
            
  let joue ~coup:(case, directions) ~couleur ~plateau =
    Plateau.set_contenu_case ~case ~couleur ~plateau;
    let retourne (direction, nombre) =
       for i = 1 to nombre do
         Plateau.set_contenu_case ~case:(case +: (i *: direction)) ~couleur ~plateau
       done
     in List.iter retourne directions
end

let compte_tout plateau =
  let noirs = ref 0 and blancs = ref 0 in
  let compte ~case = match Plateau.contenu_case ~plateau ~case with
    Blanc -> incr blancs
  | Noir -> incr noirs
  | _ -> ()
  in Plateau.iter_cases compte;
  if !blancs > !noirs then print_endline "Blanc gagne."
  else if !noirs > !blancs then print_endline "Noir gagne."
  else print_endline "Partie nulle.";
  ignore (Plateau.attend_clic ())

let attend_coup couleur coups_possibles plateau =
  let rec boucle () = 
    match Plateau.attend_clic () with
      Plateau.Quit -> exit 0
    | Plateau.Case case ->
	(try Coups.joue ~couleur ~plateau
	    ~coup:(List.find (fun coup -> Coups.case coup = case) coups_possibles)
	with Not_found -> boucle ())
    | _ -> boucle ()
  in boucle ()

let _ =
  Random.self_init ();
  let plateau = Plateau.cree () in
  Plateau.init_dessin();
  let rec boucle couleur coups_possibles =
    if couleur = Blanc then (
      let n = List.length coups_possibles in
      let coup = List.nth coups_possibles (Random.int n) in
      Plateau.redessine ~case:(Coups.case coup) ~couleur:Aucun;
      Plateau.attend_clic ();
      Coups.joue ~couleur ~plateau ~coup)
    else attend_coup couleur coups_possibles plateau;
    let redessine_cqui_faut ~case =
      if Plateau.contenu_case ~plateau ~case = couleur
      then Plateau.redessine ~case ~couleur
    in Plateau.iter_cases redessine_cqui_faut;
    let coul = autre_couleur couleur in
    let possibles = Coups.trouve ~couleur:coul ~plateau in
    if possibles = [] then (
      let re_possibles = Coups.trouve ~couleur ~plateau in
      if re_possibles = [] then compte_tout plateau else (
      print_endline ("Le joueur " ^ (match couleur with
	Blanc -> "Noir "
      | Noir -> "Blanc "
      | _ -> "") ^ "passe son tour");
      boucle couleur re_possibles))
    else boucle coul possibles
  in boucle Noir (Coups.trouve ~couleur:Noir ~plateau)

avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

78

y a plus de smileys tristes que de smileys contents, c bien la preuve que caml çay mal cheeky

et puis modulaire, bof, tu vois le nb d'occurrences de 8 et 7 dans le code ? tongue

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

79

lol
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

80

- (t'as p-ê pas lu because edit furtif) plein de 8 et 7 hardcodés
- (match couleur with Blanc -> "Noir " | Noir -> "Blanc " | _ -> "") -> sick
- let ( +: ) = Plateau.avance_dir let ( *: ) = Plateau.mult_dir -> miam roll
-
te;
[ul]  let noirs = ref 0 and blancs = ref 0 in 
  let compte ~case = match Plateau.contenu_case ~plateau ~case with 
    Blanc -> incr blancs 
  | Noir -> incr noirs 
  | _ -> () 
  in Plateau.iter_cases comp

c'est pas génial parce que :
* tu hardcodes blanc/noir
* une fois que tu as ton itérateur (avec iter_cases), tu ne peux pas profiter des fonctions d'itérations plus spécialisées (map, fold_left, fold_right...)

Toujours en Ruby, ça pourrait se faire avec :
compte = plateau.inject Hash.new(0) { |compte,case| compte[case]+=1 }
blancs,noirs = compte[Blanc],compte[Noir]

(sans rien définir dans Plateau)[/ul]
- et puis bon c'est quand même franchement lourd en général : "Plateau.contenu_case ~plateau ~case" -> plateau[case], "let dir = Plateau.neg_dir direction" -> !direction au lieu de dir, etc...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

81

Euh la partie interactive (tracé / gestion de la souris) c'est du vrai quick & dirty pour voir ce que ça donnait et toutes les coordonnées sont hardcodées parce que je suis un gros bourrin cheeky, mais sinon les 8 et les 7 sont tous à l'intérieur du module Plateau smile
erf sinon je m'a gouré, c'est *pas* la dernière version que j'ai mise. Bon j'édite cheeky (la principale différence c'est que la fonction attend_coup est définie à l'extérieur de la fonction principale, ce qui est quand même un peu plus propre ^^, ça doit être à peu près la seule (différence)... ah bah non y a aussi que les fonctions graphiques se retrouvent dans le module Plateau aussi, comme quoi je suis plus propre que je ne croyais ^^)
et qu'est-ce qu'il a mon match ? confus et les définitions d'opérateurs, ok elles sont peut-être pas indispensables mais bon je trouve que ça allège un peu quand même ^^
je hardcode blancs/noirs -> ben à la base c'est quand même pour faire des variantes d'othello avec deux joueurs, des trucs à trois ou plus ça serait hyper différent il me semble non ?
je ne peux pas profiter des fonctions plus spécialisées -> ben oui mais utiliser de telles fonctions ce serait présumer de la structure du plateau et c'est justement ce que je ne veux pas faire confus, et si c'était pas un array mais un truc complètement martien ? je ne mets dans l'interface que les fonctions dont j'ai besoin ça me paraît logique... après libre à lui d'en implémenter plus mais je vais pas l'obliger ; je comprends pas trop ta remarque

ta dernière remarque -> j'ai l'impression que tu appelles "lourd" ce que j'appelle "lisible" neutral
en plus après (enfin avant cheeky) tu me reproches de définir des opérateurs pour alléger, c'est pas très cohérent...
parce que là rien ne m'empêche de faire pareil hein : let ( !: ) = Plateau.neg_dir et hop c'est bon happy
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

82

C'est si bien que ça le ruby ?
avatar
I'm on a boat motherfucker, don't you ever forget

83

Sally :
Euh la partie interactive (tracé / gestion de la souris) c'est du vrai quick & dirty pour voir ce que ça donnait et toutes les coordonnées sont hardcodées parce que je suis un gros bourrin cheeky

Oué nan ça c tout-à-fait compréhensible, j'ai eu la flemme de regarder ça de toute façon happy
mais sinon les 8 et les 7 sont tous à l'intérieur du module Plateau smile

(pas avant ton édit furtif tongue) Et ? © C'est pas super quand même ^^
et qu'est-ce qu'il a mon match ? confus

C'eût été plus propre de faire une conversion en chaîne appliquée à autre_couleur ^^
et les définitions d'opérateurs, ok elles sont peut-être pas indispensables mais bon je trouve que ça allège un peu quand même ^^

Nan ct juste un troll parce que "+:" ça ressemble vraiment à rien et que si t'as 50 classes du style de Plateau.dir tu vas t'amuser avec des "+:$#" :]
je hardcode blancs/noirs -> ben à la base c'est quand même pour faire des variantes d'othello avec deux joueurs, des trucs à trois ou plus ça serait hyper différent il me semble non ?

Ouais bon cheeky Mais ce serait plus propre si ct séparé ^^ (le pb n'étant pas tant que ça serait très différent, c'est surtout que ça sert à rien de redire 50000 fois que l'ensemble des joueurs est bel et bien {Blanc,Noir})
je ne peux pas profiter des fonctions plus spécialisées -> ben oui mais utiliser de telles fonctions ce serait présumer de la structure du plateau et c'est justement ce que je ne veux pas faire confus

Nan, t'as pas lu la parenthèse avec mes exemples : fold_right, par exemple, n'a besoin que d'un itérateur sur l'objet ; find aussi, etc... Enfin ça par contre j'imagine que ça doit être possible en caml avec des modules, mais bon c'est dommage que la lib standard ne soit pas faite autour de ça... (et que donc en pratique personne ne s'en serve)

Si tu regardes mon exemple en Ruby avec ma classe LinkedList à la place des tableaux, tu verras que j'ai juste défini l'itérateur "each", et le "include Enumerable" me fait hériter d'un paquet de fonctions (dont, par exemple, "find" qui me sert après pour chercher les nombres premiers, ou "to_a" qui me sert pour convertir en un tableau)
et si c'était pas un array mais un truc complètement martien ?

Ca marche aussi smile
je ne mets dans l'interface que les fonctions dont j'ai besoin ça me paraît logique... après libre à lui d'en implémenter plus mais je vais pas l'obliger ; je comprends pas trop ta remarque

Justement, c tout ce qu'il y a de plus standard ^^
ta dernière remarque -> j'ai l'impression que tu appelles "lourd" ce que j'appelle "lisible" neutral

Gnî ?
$stderr.print key.to_s+" -> "+hash[key]
c'est moins lisible que
File.print_string stderr (string_of_key key ^ " -> " ^ (MyHashTable.get_item hash key))
???

Au contraire, tu réécris pas 50x la même chose...
en plus après (enfin avant cheeky) tu me reproches de définir des opérateurs pour alléger, c'est pas très cohérent...

Nan au contraire, c'est pas le problème, c'est très bien mais justement le fait qu'il n'y ait qu'un seul namespace et pas de surcharge fait que c'est le bordel et que c'est pas très lisible... (et que donc tu vas devoir limiter sérieusement le nb de fois où tu fais appel à ce genre d'opérateur pour que ça reste vaguement lisible)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

84

Flanmou(love)>
Non, pas tant que ça, disons que c'est pas encore extrêmement répandu donc y a des petits côtés "amateur" comme dans Caml...

En fait ce qu'il y a de bien :
- l'orientation objet est assez bien foutue, et est vraiment très pratique (contrairement à OCaml), avec une très bonne encapsulation
- la lib standard contient pas mal de trucs (mais évidemment c pas non plus Perl, donc tu vas pas trouver des libs qui gèrent le FJIXKZML) et a globalement une API bien pensée et intuitive (pas comme Java ou PHP ^^)
- la syntaxe est presque aussi concise que Perl pour les trucs genre manipulation de texte (avec chaînes, regexp, tableaux, hash...), et pour les trucs avec des structures de données un peu plus poussées elle est bien plus efficace (les tableaux de tableaux en Perl demandent de faire des espèces de hacks et ont une syntaxe infâme sick)
- y a même un call/cc love
mais :
- c'est du typage dynamique, donc plutôt orienté scripts
- l'interpréteur est tout sauf un foudre de guerre, il y a une version plus efficace en cours de développement mais elle ne sera pas parfaite non plus (à cause du typage dynamique, de la gestion transparente d'entiers de tailles arbitraires, on ne peut pas faire un compilateur très efficace par exemple -- un peu comme le TI-Basic)
- la portée des variables est lexicale (encore heureux smile), mais il n'y a jamais de déclaration explicite et les règles sont parfois un peu bizarres (ça devrait changer dans une prochaine version)
- y a des petits trucs qui font tâche dans la lib standard (par exemple, Unicode est pas super bien supporté pour l'instant couic2 mais bon ça devrait changer aussi)

Donc en gros c'est du Perl propre (oxymore pawa cheeky) et assez agréable, mais un peu plus lent et avec qques défauts de jeunesses...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

85

[cite]Pollux :
mais sinon les 8 et les 7 sont tous à l'intérieur du module Plateau smile

(pas avant ton édit furtif tongue)

ils étaient tous soit dans le module Plateau soit dans la partie interactive, voulais-je dire, c'était peut-être pas très clair ^^ (sinon = à part dans la partie dont je viens de parler)
Et ? © C'est pas super quand même ^^

ben le module Plateau tel qu'il est là est fait pour un plateau 8 sur 8 donc bon... certes j'aurais pu mettre des n mais bon je l'ai pas fait cheeky
et qu'est-ce qu'il a mon match ? confus
C'eût été plus propre de faire une conversion en chaîne appliquée à autre_couleur ^^

Tu veux dire que j'aurais dû définir un string_of_couleur ? mouais j'aurais pu ^^
Nan ct juste un troll parce que "+:" ça ressemble vraiment à rien et que si t'as 50 classes du style de Plateau.dir tu vas t'amuser avec des "+:$#" :]

Euh en même temps on peut pas surcharger certes, mais on peut cacher (déclarer un autre truc du même nom, je sais plus si y a un terme spécifique pour ça ?)... c'est-à-dire que tu n'as besoin de 50 suffixes différents que si tu utilises effectivement les 50 opérateurs différents au *même* endroit, or a priori tu manipules pas 50 types de structures différentes en même temps (enfin si c'était le cas évidemment ça serait pas très adapté, mais moi ça m'arrive rarement), donc franchement ça ne me gêne pas. Alors que (peut-être parce que j'ai l'habitude du caml) j'ai un peu de mal avec la surcharge (du point de vue de la lisibilité je veux dire) parce que ça oblige à regarder les types des variables pour savoir ce que ça fait (au lieu de l'inverse cheeky), enfin comme je dis c'est peut-être une simple question d'habitude. Et je réponds en même temps à ta dernière remarque : il n'est pas vrai qu'il n'y ait qu'un seul namespace, il y en a un par module. Bon après ça dépend de ce que tu veux faire concrètement, évidemment tu vas pas mettre un open toutes les trois lignes couic, mais rien ne t'empêche d'en mettre un de temps en temps et en les utilisant bien ça peut pas mal alléger je pense (par rapport à ce que ce serait sans)
Nan, t'as pas lu la parenthèse avec mes exemples : fold_right, par exemple, n'a besoin que d'un itérateur sur l'objet ; find aussi, etc.

ok picol, j'avais pas compris
ta dernière remarque -> j'ai l'impression que tu appelles "lourd" ce que j'appelle "lisible" neutral
Gnî ?

Ben cf. mes remarques sur la surcharge, plateau[case] je trouve pas ça très explicite
(même si l'interpréteur, lui, comprend, je trouve ça carrément moins lisible pour l'homme que Plateau.contenu_case ~plateau ~case : dans ce dernier cas tu vois immédiatement quelle fonction tu appliques et à quoi, ça permet de comprendre le code vachement plus rapidement, enfin ce que j'en dis...)
Quant à utiliser !direction au lieu de neg_dir direction, ben c'est possible comme je l'ai dit (enfin !: est préférable si on veut manipuler des références par ailleurs évidemment cheeky) mais c'est pareil je trouve ça moins lisible ^^
$stderr.print key.to_s+" -> "+hash[key]
c'est moins lisible que
File.print_string stderr (string_of_key key ^ " -> " ^ (MyHashTable.get_item hash key)) ???
Évidemment que non, ça peut pas être lisible si tu fous du mixed case roll
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

86

[cite]Sally :
Pollux
:
mais sinon les 8 et les 7 sont tous à l'intérieur du module Plateau smile

(pas avant ton édit furtif tongue)
ils étaient tous soit dans le module Plateau soit dans la partie interactive, voulais-je dire, c'était peut-être pas très clair ^^ (sinon = à part dans la partie dont je viens de parler)

Hmm nan désolé c de ma faute g répondu à ton post avant de le lire (cheeky) donc ta phrase s'est retrouvée coupée en deux ^^
et qu'est-ce qu'il a mon match ? confus
C'eût été plus propre de faire une conversion en chaîne appliquée à autre_couleur ^^
Tu veux dire que j'aurais dû définir un string_of_couleur ? mouais j'aurais pu ^^

L'idéal serait même que ça soit builtin tongue
Nan ct juste un troll parce que "+:" ça ressemble vraiment à rien et que si t'as 50 classes du style de Plateau.dir tu vas t'amuser avec des "+:$#" :]
Euh en même temps on peut pas surcharger certes, mais on peut cacher (déclarer un autre truc du même nom, je sais plus si y a un terme spécifique pour ça ?)...

couiccouiccouic
mais c'est affreux ça ! Ca veut dire que tu peux même pas faire de copier-coller de code, ou déplacer du code...
C'est précisément tout le contraire de la "philosophie" © fonctionnelle, où en principe les effets de bords devraient être réduits au minimum et tout et tout embarrassed M'enfin bon je veux bien croire que c'est pas un défaut intrinsèque de Caml, juste un truc mal implémenté cheeky
Alors que (peut-être parce que j'ai l'habitude du caml) j'ai un peu de mal avec la surcharge (du point de vue de la lisibilité je veux dire) parce que ça oblige à regarder les types des variables pour savoir ce que ça fait (au lieu de l'inverse cheeky)

Ben si t'as une variable qui s'appelle "plateau", elle va être de type ? hmm ? Et "case" ? et "couleur" ?
Et je réponds en même temps à ta dernière remarque : il n'est pas vrai qu'il n'y ait qu'un seul namespace, il y en a un par module.

Je veux dire : les opérateurs sur les entiers sont dans le même namespace que les opérateurs sur les foobars bleutés...

ta dernière remarque -> j'ai l'impression que tu appelles "lourd" ce que j'appelle "lisible" neutral
Gnî ?
Ben cf. mes remarques sur la surcharge, plateau[case] je trouve pas ça très explicite

Euh là je soupçonne que c vraiment une question d'habitude, mais pour moi c'est on ne peut plus limpide confus
tableau[index]
hash["clé"]
plateau[coord]
c'est vraiment la même chose...
(même si l'interpréteur, lui, comprend, je trouve ça carrément moins lisible pour l'homme que Plateau.contenu_case ~plateau ~case : dans ce dernier cas tu vois immédiatement quelle fonction tu appliques et à quoi, ça permet de comprendre le code vachement plus rapidement, enfin ce que j'en dis...)

Mouais je vois pas l'intérêt à part être 2.5x plus long...
Quant à utiliser !direction au lieu de neg_dir direction, ben c'est possible comme je l'ai dit (enfin !: est préférable si on veut manipuler des références par ailleurs évidemment cheeky)

Oui nan bien sûr (en fait j'avais pas fait gaffe, c'est pour les directions et pas pour les couleurs donc ce serait plutôt -: smile)
mais c'est pareil je trouve ça moins lisible ^^

hum
x +: n *: d c'est lisible
mais
x +: n *: (-: d) c'est pas lisible ???

(bon d'accord les : sont lourds, mais c pas à moi qu'il faut le dire happy)
$stderr.print key.to_s+" -> "+hash[key]
c'est moins lisible que
File.print_string stderr (string_of_key key ^ " -> " ^ (MyHashTable.get_item hash key)) ???
Évidemment que non, ça peut pas être lisible si tu fous du mixed case roll

Mais quel psychorigide alors triroll
Alors :
$stderr.print key.to_s+" -> "+hash[key]
c'est moins lisible que
File.print_string stderr (string_of_key key ^ " -> " ^ (My_hash_table.get_item hash key)) ?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

87

Mais quel psychorigide alors
Euh c'était juste un troll j'ai pas pu résister tongue
oui non en l'occurrence c'est pas vraiment moins lisible... sinon le truc de plateau[case], en fait c'est que tu te fies vachement aux noms des variables pour comprendre le code, bon en fait pourquoi pas mais j'ai vraiment pas cette habitude (et puis c'est pas « sûr » : rien ne t'empêche d'appeler brouette une variable de type plateau, bon ok je vois pas pourquo tu le ferais à moins d'être maso mais ça pourrait être une erreur, enfin bref ^^)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

88

Ben si on permet aux programmeurs de donner des noms à leurs variables/fonctions, c'est bien pour que ça leur soit utile ... de même que les commentaires dans le source.
avatar
I'm on a boat motherfucker, don't you ever forget

89

Oui, il y a l'aspect que si ton code est 3x moins redondant, c'est un peu plus dangereux de se planter dans ce tiers-là.
Mais (outre le fait que ça fait 3x moins de code à lire, à écrire, et à vérifier) ça a la conséquence intéressante que si créer un nouveau type ne t'oblige pas à appeler "Nouveau_type.concatenate foobar bleuté" mais peut s'écrire naturellement "foobar+bleuté", alors ça devient possible d'utiliser plus souvent des nouveaux types plus spécialisés (et donc plus sûrs), à l'opposé d'Unix où "tout est un entier" (files descriptors...) parce que c'est plus facile à manipuler en l'absence de surcharge...
Euh c'était juste un troll j'ai pas pu résister tongue

oui oui, d'où mon smiley happy

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)