1. JavaScript / Говнокод #17323

    +210

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    /*
          _31 - числа  начинаются с _
          _Math_sin - глобальные функции тоже
          $abcd - строки начинаются с $ 
          /\ - символ лямбда. Easter egg:можно писать и / для краткости
          САХАР:
           args = arguments
          _ = args[0]     
    */
    
    log("========CALCULATOR EXAMPLE========");
    //*
    handler= makeHandler(chainer());
    var calc = prox(
        {   //imports
            print:function(x){log(x); return x;}
            ,add:function(a,b){ return a+b;}
            ,set:function(x,y){ return y;}
            ,fma:function(a,b,c){
                return a*b+c;
            }        
        }
    );
    calc
        .set[0]
        .add[2]
        .print //2
        .fma[10][5]
        .print //25
        
        .add._3
        .String
        .add._1111
        .print //281111
        
        ._Math_min._1
        ._Math_max._1000
        .print //100
        
        .String
        ._Math_log10
        .add["$ pow 10"]
        .print //3 pow 10
    ;
    //*/
    handler= makeHandler(chainer());
    var linq = prox(
        {   //imports
            set     :function(inner,y){ return y;}
            ,print  :function(x){log(x); return x;}
            ,map    :function(arr,y){ return arr.map(y)}
            ,filter :function(arr,y){ return arr.filter(y)}
            ,sort   :function(arr,comparator){ return arr.sort(comparator)}
            //Imperatii
            ,IF     :function(context,condition,trueBranch,falseBranch){
                return (condition(context)) ? trueBranch(context) : falseBranch(context);
            }
        }
    );
    
    linq
        .set    ["[5,2,1,3,4]"]
        .print//[5, 2, 1, 3, 4]
        .map    ["/\ _ * 3"]
        .print//[15, 6, 3, 9, 12]   
        .filter ["/\ log('filter='+args[0]),args[0]>5"] //несколько операторов в лямбде.
        .print//[6, 9, 12, 15]
        .sort   ["/\ args[0]-args[1]"]
        .map    ["/\ _ - 6"]
        .print//[0, 3, 6, 9]
        .map    ["/\ 2>_ ? 1 : _ * args.callee(_-1)"]   //анонимная рекурсия и факториал
        .print//[1, 6, 720, 362880]
        
        //имперации
        .filter ["/\ _>100"]
        .IF ["/\ _.length===0"][ 
            "/\ log('array is EMPTY!'), _" 
        ][ 
            "/\ log('Not empty:',_), []"         
        ]    //"Not empty:" [720, 362880]
        .IF ["/\ _.length===0"][ 
            "/\ log('EMPTY!'), ['empty','replacement']" 
        ][ 
            "/\ log(_), _"         
        ].print//['empty','replacement']
           
    ;

    Такой вот DSL на свойствах javascript.
    Осторожно! Все трюки выполнены профессионалами. Не пытайтесь повторить это на работе.
    http://jsfiddle.net/y5og4o9q/1/

    Запостил: 3.14159265, 15 Декабря 2014

    Комментарии (18) RSS

    • //это его оживляет
      var log=console.log;
      var handler;
      function prox(obj){
          var p=Proxy(obj, handler);
          p.valueOf=function(){return obj.res}
          return p;
      }
      
      var makeHandler = function(act){
          return {
              get: function(target, name){    
                  if(name in Object.prototype) 
                      return target[name];
                  return prox(act(target,name));
              }
          };
      };
      
      var chainer=function()
      {
      
          var args=[]; var arity=0; var fn;
          var deepLook=function(o,key){
              var a = key.split('_');
              while (a.length) {
                  var n = a.shift();
                  if (!(n in o))
                      return;
                  o = o[n];
              }
              return o;
          };
          return function(space,name)
          {
              var arg;
              var scoped=0;
              if (name){
                  if ("_"===name.charAt(0)){
                      var x=name.substring(1);
                      arg =  (x == +x) ?  +x : (scoped=1, deepLook(window,x));
                  }else if ( -1<"{[".indexOf(name.charAt(0)) ){
                      arg=JSON.parse(name);
                  }else if ("/"===name.charAt(0)){    
                      //копеляция
                      arg=Function("var args=arguments; var _=args[0]; return "+name.substring(1)+";");            
                  }else if ("$"===name.charAt(0)){
                      arg = name.substring(1);
                  } else{
                      scoped=true;
                      arg= (name == +name) 
                          ?  +name
                          :(space[name]===void(0)) 
                              ? window[name] 
                              : space[name]; //scoping
                  }
              }
              //scoped=false; функцию передаём как аргумент. 
              if (scoped && typeof arg === "function"){
                  fn=arg;
                  arity=fn.length;
              }else{
                  args.push(arg);
              }        
              
              if (arity<=args.length+1){
                  space.res=fn.apply(this, [space.res].concat(args));
                  args=[];
              }            
              return space;  
          }
      }
      Ответить
      • > var p=Proxy(obj, handler);
        > var log=console.log;
        Это вообще работать не должно, а если где и работает - это огнелис с фаербагом.
        Ответить
        • > var p=Proxy(obj, handler);
          >Это вообще работать не должно, а если где и работает - это огнелис с фаербагом.
          Денис, а что же ты тогда своих читателей на волан-де-сайте обманываешь?

          Chrome, например, довольно давно поддерживает Proxy.
          Node.js использует V8 — тот же javascript движок, что и Chrome, соответственно, он должен поддерживать те же новые возможности языка.

          http://www.peeep.us/7327b96c
          Ответить
          • > Денис, а что же ты тогда своих читателей на волан-де-сайте обманываешь?
            Действительно.

            Я запускаю node 0.11.14 с ключом --harmony. Proxy там есть, но не работает.
            Это я кривой или вместо Proxy заглушка?
            Ответить
            • https://github.com/tvcutsem/harmony-reflect с такой штукой, разве что, работать будет, а вообще ответил ниже.
              Ответить
              • Спасибо, создал прокси в старом стиле, стало легче.
                Ответить
          • В V8 старая реализация Proxy, они создаются через Proxy.create, а в последних сборках вообще выпилена. Кстати, это да, это моя статья :) А работать вообще не должно потому, как по стандарту вызов Proxy без new должен вызывать ошибку (хоть пока в огнелисе и работает).
            log должен вызываться из контекста консоли, а тут он к нему не привязывается - в Chrome и FF без фаербага будет ошибка.
            Ответить
            • Я уж про этот раритет и забыл, перечитаю, посмеюсь над собой :)
              Ответить
    • Поправлено:
      http://jsfiddle.net/y5og4o9q/2/
      Типа пример "перегрузки операторов" [] .
      Ответить
    • brainfuck()
      
        .plus .plus .plus .plus .plus .plus .plus 
        .plus .plus .plus .plus .plus .plus .plus
        .begin
              .minus.next .plus .plus .plus .plus
              .plus .next .plus .plus .plus .plus
              .plus .plus .next .plus .plus .plus
              .plus .plus .plus .prev .prev .prev
        .end
        .next .plus .print.next .minus.minus.minus
        .minus.minus.print.next .plus .plus .print
        .prev .minus.print.plus .print.minus.minus
        .minus.minus.print.plus .plus .plus .plus
        .print.prev .minus.minus.minus.print


      http://ideone.com/PGxQrX
      Ответить
      • Кстати заметьте чудо-if похож на nemerle/scala. С возвратом значения.
        Ответить
    • Ура, товарищи! Я снова могу ходить сидеть на уютненьком говнокодике!
      Ответить
    • 3.14159265, возможно, эти темы, выбранные автоматически вручную на основе Ваших предпочтений, Вам понравятся:
      http://govnokod.ru/20105
      http://govnokod.ru/20110
      Ответить
      • Ух, ты! Действующий пузырь фильтров!

        А сможете ещё кому-нибудь составить рекомендации?
        Ответить
    • Хороша идея!
      Можно эвалить куски кода на J прямо в JavaScript!
      Ответить

    Добавить комментарий