본문으로 이동

JS++

위키백과, 우리 모두의 백과사전.
JS++
Image
패러다임다중 패러다임: 명령형, 구조적, 객체 지향, 함수형, 제네릭
계열ECMA스크립트
설계자로저 푼(Roger Poon), 안톤 라페토프(Anton Rapetov)
개발자Onux
발표일2011년 10월 8일(15년 전)(2011-10-08)
최근 버전0.10.0
최근 버전 출시일2021년 12월 10일(4년 전)(2021-12-10)
자료형 체계점진적, 정적, 동적
변수 영역렉시컬
라이선스BSD
파일 확장자.jspp, .js++, .jpp
웹사이트www.onux.com/jspp
영향을 받은 언어
C, C++, C#, 자바, 자바스크립트

JS++는 자바스크립트를 건전한 타입 시스템으로 확장한 웹 개발용 프로그래밍 언어이다. 이 언어는 명령형, 객체 지향, 함수형, 그리고 제네릭 프로그래밍 기능을 포함한다. BSD 라이선스로 배포되는 자유-오픈 소스 소프트웨어이다.

역사

[편집]

JS++은 2011년 10월 8일에 처음 등장했다.[1][2][3] 현대적인 구현체는 2016년 DeveloperWeek에서 발표되었으며[4] 2016년 5월 31일에 출시되었다.[5][6][7][8] 이 언어는 로저 푼과 안톤 라페토프가 설계했다.

기능

[편집]

건전한 점진적 타입 시스템

[편집]

JS++은 자바스크립트의 상위 집합이므로 변수에 대한 자료형 선언은 선택 사항이다. 그러나 타입을 선언하면 컴파일 타임과 런타임 모두에서 타입이 강제된다.

JS++의 타입 어노테이션은 전통적인 C/C++ 문법을 사용한다.

int x = 1;
var y = 2;
bool z = true;

특히 이는 더 장황한 스타일을 사용하는 타입스크립트 및 액션스크립트와 차별화된다.

var x: number = 1;
var y: any = 2;
var z: boolean = true;

JS++의 타입 시스템은 호스트 객체, 동적 키-값 쌍, 코멧, J스크립트 조건부 컴파일, 동적 반환 타입, 액티브X, ECMAScript for XML, 웹 브라우저 가비지 컬렉터 및 순환 참조 카운팅 버그, 조건부 논리, 그 외의 다양한 엣지 케이스를 포함하는 ECMA스크립트 및 DOM API의 예외적인 상황에 대해 건전하다.[9][10] 이는 타입스크립트와 같이 타입이 선택 사항이며 타입 소거를 통해 런타임에 제거되는 다른 자바스크립트 상위 집합과는 다르다.[11][12]

자바스크립트 라이브러리 가져오기

[편집]

JS++은 다음의 JS++ 홈페이지 예제와 같이 한 줄의 external 문을 사용하여 자바스크립트 라이브러리를 사용할 수 있다.

import System;
// 한 줄의 코드로 자바스크립트 라이브러리 가져오기
external jQuery, $;

class Example {
    public Example() {
        // 학습 곡선이 거의 없음
        // 일반 자바스크립트를 계속 작성할 수 있음
        var a = 0, random = Math.random();
        // 정수 타입 및 기타 원시 타입
        // ... 빠른(최적화된) 코드와 명확한 코드를 가능하게 함
        byte[] rgbColors = [ 0xFF, 0xFA, 0xFF ];
    }

    public void showMessage(int id, string text) {
        // 일반 자바스크립트와 100% 호환
        jQuery("#msgbox").show();
        $("#msgbox").text(id.toString() + text);
    }
}

객체 지향 프로그래밍

[편집]

자바스크립트 (ECMA스크립트 6)의 클래스가 내부적으로는 프로토타입을 위한 신택틱 슈거인 반면,[13] JS++의 클래스는 메모리 레이아웃, 성능, 의미론적 측면에서 C++, 자바, C#과 같은 고전적인 프로그래밍 언어에서 볼 수 있는 클래스와 유사하다. "클래스"는 정적 개념이며, 자바스크립트, 스몰토크, 리스프, 타입스크립트처럼 프로토타입에 의존하여 런타임(프로그램 실행 중)에 변경할 수 없다.[14] 예를 들어, private 메소드는 컴파일 타임과 런타임 모두에서 private 상태를 유지하며, 자바스크립트에서 JS++ 객체에 대한 참조를 얻더라도 외부 자바스크립트 객체는 JS++의 private 필드나 메소드에 접근할 수 없다.

예제: 객체 지향 정렬

[편집]

다음 소스 코드는 타입 안전하고 가독성 높은 비교를 위해 IComparable<T> 인터페이스와 Comparison 열거형을 사용하는 JS++의 객체 지향 정렬을 보여준다.[15] 사용자 정의 정렬 로직은 아래의 오버라이드된 compare 메소드에서 한 줄의 코드로 구현된다.

import System;

class Employee : IComparable<Employee> {
    private string firstName;
    private string lastName;

    public Employee(string firstName, string lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public override Comparison compare(Employee that) {
        // 성(surname)으로 정렬
        return this.lastName.compare(that.lastName);
    }

    public override string toString() {
        return this.firstName + " " + this.lastName;
    }
}

Employee zig = new Employee("Zig", "Ziglar");
Employee john = new Employee("John", "Smith");
Employee abe = new Employee("Abe", "Lincoln");

Employee[] employees = [ zig, john, abe ];
employees.sort();
Console.log(employees.join(", "));
Abe Lincoln, John Smith, Zig Ziglar

위의 코드에서 제공된 사용자 정의 정렬 로직은 다음과 같다.

return this.lastName.compare(that.lastName);

마찬가지로, 정렬 호출은 다음과 같다.

employees.sort();

정렬된 결과 출력은 다음과 같다.

Console.log(employees.join(", "));

예제: 기본 캡슐화

[편집]

JS++은 기본적으로 캡슐화를 제공한다. 다음 예제에서 x와 y 필드는 접근 제어자가 지정되지 않아도 기본적으로 private이다. getX()와 getY() 메소드는 기본적으로 public이다. 이를 통해 아래 Point 클래스에서 볼 수 있듯이 더 간결한 클래스 정의 문법이 가능하다.[16]

class Point {
    int x, y;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    int getX() {
        return this.x;
    }

    int getY() {
        return this.y;
    }
}

경계 외부(Out-of-bounds) 분석

[편집]

경계 외부(out-of-bounds) 접근은 일반적으로 배열 및 기타 컨테이너에서 발생한다. 예를 들어, 3개 요소로 구성된 배열의 100번째 요소에 접근하면 경계 외부 접근이 발생한다.

int[] arr = [ 1, 2, 3 ];
Console.log(arr[100]); // 경계 외부 접근, 'arr'은 인덱스 100에 요소가 없음

자바나 C#에서는 이로 인해 예외가 발생하고 프로그램이 종료될 수 있다. C에서는 버퍼 오버플로나 세그멘테이션 오류가 발생할 수 있다. C++은 기본 초기화, 예외, 세그멘테이션 오류, 버퍼 오버플로 등 다양한 의미론을 가진다.[17][18]

JS++은 컴파일 타임에 경계 외부 오류를 효율적으로 분석하고 방지할 수 있다.[19][20][21]

자바스크립트에는 null과 undefined 값이 존재하는데, null은 값이 존재하지만 빈 값임을 의미하고, undefined는 값이 전혀 없음을 의미한다. JS++은 이 직관을 더 확장하여 빈 값과 경계 외부 접근을 구분한다.[21]

int?로 표현되는 널러블 int 타입이 있는 다음 코드를 고려하자.

int[] a = [ 1, 2 ];
int? value1 = a[2];
if (value1 == null) {
    Console.log("분명히 경계 외부임");
}

int?[] b = [ 1, null ];
int? value2 = b[2];
if (value2 == null) {
    Console.log("경계 외부일 수도 있고, 단순히 null 요소에 접근했을 수도 있음");
}

널러블 타입이 경계 외부 접근을 나타낼 수는 있지만, 위와 같이 배열이 널러블 값을 포함할 수 있는 경우에는 작동하지 않는다. 대신 JS++은 널 값 외에 추가적인 개념인 '정의되지 않은(undefined) 값'을 도입한다. JS++은 자바스크립트의 개념을 확장하여 null은 값이 있지만 빈 값임을, undefined는 값이 아예 존재하지 않음을 의미하도록 한다. JS++은 "값이 아예 존재하지 않음"이라는 개념을 경계 외부 접근이 발생했음을 의미하는 것으로 사용하며, 이 개념은 JS++에서 "존재 타입(existent types)"으로 알려져 있다.[21]

따라서 이전 예제를 수정할 수 있다. 존재 타입 int+는 "int 또는 경계 외부"를 의미하고, int?+는 "int, null, 또는 경계 외부"를 의미한다.

int[] a = [ 1, 2 ];
int? value1 = a[2];
if (value1 == undefined) {
    Console.log("분명히 경계 외부임");
}

int?[] b = [ 1, null ];
int?+ value2 = b[2];
if (value2 == undefined) {
    Console.log("분명히 경계 외부임");
}

직관적으로 이는 존재 타입을 배열 요소의 기본 타입으로 사용할 수 없음을 의미한다. JS++은 이를 컴파일 타임에 강제한다.

int+[] arr = []; // 오류
[ 오류 ] JSPPE5204: 존재 타입 `int+'는 배열의 요소 타입으로 사용할 수 없음

경로 폭발과 지수적인 컴파일 시간을 초래할 수 있는 모든 조건부 분기나 가상 메소드 호출 경로를 따르는 대신, 존재 타입은 기본적으로 int, bool 및 기타 원시 타입과 동일한 컴파일 타임 분석 비용을 가진다. 결과적으로 컴파일 시간은 존재 타입 도입의 영향을 받지 않는 것으로 나타났다(±1-2ms).[21] 존재 타입은 JS++의 모든 배열 및 컨테이너 타입(예: 해시 맵, Stack<T>, Queue<T>)에 사용되므로 JS++ 컨테이너는 경계 외부 오류가 발생하지 않음이 보장된다.

JS++에서 undefined는 변경할 수 없는 값이다. 자바스크립트 (ECMA스크립트 3)에서 undefined는 전역 객체의 변경 가능한 속성이어서 "undefined"가 "정의"될 수 있는 상황이 발생할 수 있다.[22] 따라서 순수 자바스크립트에서는 존재 타입을 구현할 수 없는데, 이는 배열에 undefined 값이 포함될 수 있고, undefined가 정의될 수 있으며, JS++에서 방지되는 다른 예외 사례들 때문이기도 하다.[21][23]

또한 자바나 에펠과 같은 초기 객체 지향 언어들과 비교하여,[24][25] JS++은 객체를 null로 기본 초기화하지 않는다.[21] 대신 컴파일러가 프로그래머에 의한 초기화를 강제한다.

class Car {}

Car car;
[  오류  ] JSPPE6000: 변수 `car'가 3행 4열에서 초기화되지 않음

따라서 존재 타입이 언어에 깊이 내장되어 있으므로 JS++은 경계 외부 오류가 절대 발생하지 않음을 보장할 수 있다.[26][10]

데이터베이스

[편집]

존재 타입의 개념은 컨테이너 외부로 확장될 수 있다. 예를 들어 MySQL에서 컬럼은 널러블일 수 있다.[27][28] 특정 조건(예: WHERE 절)에 대해 행이 존재하지 않으면 undefined 값이 반환될 수 있다. 그러나 행은 존재하지만 해당 컬럼의 값이 비어 있는 경우 대신 null 값이 반환될 수 있다. 이는 데이터 접근 계층으로의 코드와 인터페이스를 단순화할 수 있다.

정수 타입

[편집]

JS++은 8비트, 16비트, 32비트, 64비트 정수 타입뿐만 아니라 부동 소수점 타입을 제공한다.

byte b1 = 0xFF;        // 부호 없는 8비트
signed byte b2 = -1;   // 부호 있는 8비트
short s1 = 1;          // 부호 있는 16비트
unsigned short s2 = 1; // 부호 없는 16비트
int x1 = 0;            // 부호 있는 32비트
unsigned int x2 = 0;   // 부호 없는 32비트
long z1 = 1;           // 부호 있는 64비트
unsigned long z2 = 1;  // 부호 없는 64비트

float f = 0.5;         // 단정밀도 부동 소수점
double d = 0.5;        // 배정밀도 부동 소수점

프로젝트 홈페이지의 예제:

// 변수의 타입을 선언할 필요가 없으며 일반 자바스크립트를
// 그대로 계속 작성할 수 있음 (다시 한번 말하지만, 학습 곡선이 없음):
var offset = 0;

// 하지만 타입을 선언하면, 이 다음 변수는 런타임에서도 항상 'unsigned int'로 유지됨.
// 다시는 NaN("Not a Number") 런타임 오류를 보지 않아도 됨.
// 이 변수는 'unsigned'이므로 음수가 되지 않음이 보장됨.
unsigned int pageHeight = $(document).height();

블록 범위(Block scoping)

[편집]

자바스크립트 var 문을 포함하여 JS++의 모든 변수는 블록 범위이다.[29][30][31] 따라서 자바스크립트 (ECMA스크립트 6)에서 var와 let이 동시에 존재하는 것처럼 서로 다른 범위 규칙을 가진 두 가지 변수 선언 키워드가 필요하지 않다.

개발 도구

[편집]

컴파일러

[편집]

JS++ 컴파일러는 윈도우, MacOS, 리눅스에서 사용할 수 있다. 이 컴파일러는 중간 표현으로서 자바스크립트 소스 코드를 내보내는 소스 대 소스 컴파일러이다.

컴파일러는 C/C++로 개발되었으며, 개발자들은 3.5년의 엔지니어링과 40만 줄의 코드 끝에 "핵심 컴파일러에 열린 버그 보고서가 10개 미만"이라고 주장한다.[31][32]

편집기 통합

[편집]

JS++은 비주얼 스튜디오 코드, 아톰, 서브라임 텍스트를 포함한 다양한 코드 편집기와 통합된다.[33][34][35]

빌드 도구

[편집]

JS++은 웹팩과 같은 타사 빌드 도구와 통합할 수 있다.[36]

릴리스 기록

[편집]
버전 번호 릴리스 날짜 변경 사항
0.01 2011년 10월 8일 알파 버전, 최초 릴리스
0.011 2011년 10월 10일 알파 버전
0.012 2011년 10월 25일 알파 버전
0.013 2012년 1월 29일 알파 버전
0.014.1 2012년 8월 15일 알파 버전
0.4.1 2016년 5월 31일 베타 버전, 배열 및 콜백 타입, 문자 리터럴, 정수형 접미사, ECMAScript ASI 제거
0.4.2 2016년 10월 18일 모듈, 함수 오버로딩, 데드 코드 제거, 편집기 통합
0.4.2.1 2016년 10월 24일 버그 수정
0.4.2.2 2016년 11월 17일 소스 맵 디버깅
0.4.2.4 2016년 12월 25일 Mac OS X 지원, C 스타일 캐스트, 콜백 및 배열 변환
0.5.0 2017년 3월 13일 클래스
0.5.1 2017년 3월 26일 'foreach' 루프
0.5.2 2017년 7월 27일 BSD 허가서, 인터페이스, 추상 클래스, 가상 메소드, 자동 박싱
0.7.0 2017년 10월 27일 Array<T> 및 표준 라이브러리를 통한 모든 ECMA스크립트 3 기능
0.8.0 2018년 3월 15일 제네릭 프로그래밍, Dictionary<T>, 멀티라인 문자열, .js++ 파일 확장자
0.8.1 2018년 3월 27일 auto, catch-all 절, 시간 처리를 위한 표준 라이브러리 모듈, 버그 수정
0.8.4 2018년 5월 23일 새로운 문자열 함수, 고급 제네릭, 버그 수정, 표준 라이브러리 확장
0.8.5 2018년 6월 2일 버그 수정
0.8.10 2018년 11월 24일 더 빠른 컴파일 시간, 스택, 큐, 유니코드, 베이스64, 제네릭 기본 제약 규칙
0.9.0 2019년 1월 11일 효율적인 컴파일 타임 경계 외부 오류 분석
0.9.1 2019년 7월 1일 버그 수정
0.9.2 2019년 10월 18일 최종(불변) 변수 및 macOS 카탈리나를 위한 64비트 컴퓨팅 기본 설정

같이 보기

[편집]

각주

[편집]
  1. ↑ “JavaScript++: New, Powerful Language for Better Web Development”. 2011년 10월 17일. 2011년 10월 17일에 원본 문서에서 보존된 문서.
  2. ↑ “C++ et Javascript = Javascript++”. 《La ferme du web》. 2011년 10월 12일. 2011년 10월 12일에 원본 문서에서 보존된 문서.
  3. ↑ “Index of /downloads”. 2011년 10월 18일. 2011년 10월 18일에 원본 문서에서 보존된 문서.
  4. ↑ “JavaScript Conference - DeveloperWeek 2016 - February 12–18”. 2016년 2월 13일. 2016년 2월 13일에 원본 문서에서 보존된 문서.
  5. ↑ Poon, Roger (2016년 5월 31일). “JS++ Goes Into Public Beta”. 《Onux.com》.
  6. ↑ Handy, Alex (2016년 6월 1일). “Onux seeks to fix JavaScript's lack of type safety”. 《SD Times》.
  7. ↑ Krill, Paul (2016년 6월 6일). “New compiler tackles JavaScript's weak typing”. 《InfoWorld》.
  8. ↑ Cimpanu, Catalin (2016년 6월 9일). “jQuery 3.0 Released and Other JavaScript News”. 《Softpedia》.
  9. ↑ “The JS++ Type System, Appendix B: Problems (Why was this hard to solve?)”. 2020년 2월 10일에 확인함.
  10. 1 2 US patent 10296313, Roger Poon, "Safely consuming dynamically-typed code from a statically-typed programming language", published 2019-05-21
  11. ↑ Bridgwater, Adrian (2016년 6월 13일). “Onux JS++, an answer to JavaScript 'brittle' type safety?”. 《Computer Weekly》. 2016년 7월 22일에 원본 문서에서 보존된 문서.
  12. ↑ “The JS++ Type System”. 《Onux.com》.
  13. ↑ “Classes”. MDN 웹 문서. 2025년 6월 20일에 확인함.
  14. ↑ Meyer, Bertrand (1988). 《객체 지향 소프트웨어 구성》. 94,100쪽.
  15. ↑ Poon, Roger (2019년 5월 28일). “Tips & Tricks: Object-oriented Sorting in JS++ with IComparable<T>”. 2025년 6월 20일에 확인함.
  16. ↑ Poon, Roger (2018년 6월 10일). “Tips & Tricks: Only Fields are 'private' by Default”. 2025년 6월 20일에 확인함.
  17. ↑ “std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::operator[] - cppreference.com”. 《en.cppreference.com》. 2025년 6월 20일에 확인함.
  18. ↑ “std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::at - cppreference.com”. 《en.cppreference.com》. 2025년 6월 20일에 확인함.
  19. ↑ Díaz, Fabio (2019년 1월 23일). “JS++, the JavaScript superset, is getting rid of out-of-bounds errors”. 《Akuaroworld》. 2019년 2월 1일에 원본 문서에서 보존된 문서. 2019년 2월 1일에 확인함.
  20. ↑ Cardoza, Christina (2019년 1월 16일). “JS++ programming language looks to solve out-of-bounds errors”. 《SD Times》.
  21. 1 2 3 4 5 6 Poon, Roger (2019년 1월 11일). “JS++ 0.9.0: Efficient Compile Time Analysis of Out-of-Bounds Errors”. 《Onux.com》.
  22. ↑ “ECMAScript Language Specification”. Ecma 인터내셔널. 2000년 3월 24일: 86.
  23. ↑ “Compatibility with JavaScript - JS++ & JavaScript Documentation”. 2025년 6월 20일에 확인함.
  24. ↑ Meyer, Bertrand (1988). 《객체 지향 소프트웨어 구성》. 70–77쪽.
  25. ↑ “Void-safety: Background, definition, and tools”. 에펠. 2025년 6월 24일에 확인함.
  26. ↑ US patent 11023214, Roger Poon & Anton Rapetov, "Preventing runtime out-of-bounds errors and exceptions with nominal types", published 2021-06-01
  27. ↑ “MySQL :: MySQL 8.4 Reference Manual :: 13.6 Data Type Default Values”. MySQL. 2025년 6월 20일에 확인함.
  28. ↑ “MySQL :: MySQL 8.4 Reference Manual :: 5.3.4.6 Working with NULL Values”. MySQL. 2025년 6월 20일에 확인함.
  29. ↑ “Scoping - JS++ & JavaScript Documentation”. 2025년 6월 24일에 확인함.
  30. ↑ “Compatibility with JavaScript - JS++ & JavaScript Documentation”. 2025년 6월 24일에 확인함.
  31. 1 2 “JS++ 0.9.1: Bug Fixes”. July 2019.
  32. ↑ Poon, Roger (2019년 10월 9일). “Compiler Software Engineering Methods”. 2025년 6월 24일에 확인함.
  33. ↑ “JavaScript superset JS++ adds dead code elimination and more”. 《컴퓨터월드》. 2016년 10월 19일. 2019년 2월 1일에 원본 문서에서 보존된 문서. 2026년 6월 20일에 확인함.
  34. ↑ Cardoza, Christina (2016년 10월 19일). “JS++ 0.4.2 released with code editor integrations, modules and dead code elimination”. 《SD Times》.
  35. ↑ Clark, Geneva (2016년 10월 20일). “JS++ 0.4.2 Release - Upgraded With Modular Design, Dead Code Elimination, and Multiple Code Editors”. 《Zeomag》.
  36. ↑ Phoenix, Ingwie (2018년 12월 7일). “Proof of Concept: Using JS++ with WebPack”. 《깃허브》. Ingwie Phoenix.